diff --git a/Cargo.lock b/Cargo.lock index 073a874..ba8fd2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "anstream" version = "0.5.0" @@ -50,11 +56,55 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitfield-struct" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48adbf9313c68e023d32f441d19942226212ade3999fb22872c37a70a1b5366a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bmp" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69985ff4f58085ac696454692d0b646a66ad1f9cc9be294c91dc51bb5df511ae" +dependencies = [ + "byteorder", +] + +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "camino" @@ -71,6 +121,8 @@ version = "0.1.1" dependencies = [ "cargo_metadata", "clap", + "cytryna", + "image", "rustc_version", "semver", "serde", @@ -110,6 +162,12 @@ dependencies = [ "libc", ] +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" version = "4.4.4" @@ -142,7 +200,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.37", ] [[package]] @@ -151,12 +209,55 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cytryna" +version = "0.1.3" +source = "git+https://github.com/Maccraft123/cytryna.git?rev=ab2b9062d833911d87476f9e6cbb2cdb5517a579#ab2b9062d833911d87476f9e6cbb2cdb5517a579" +dependencies = [ + "bitfield-struct", + "bitflags 2.4.1", + "bmp", + "derivative", + "hex", + "hex-literal", + "image", + "memoffset", + "static_assertions", + "thiserror", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "errno" version = "0.3.3" @@ -178,12 +279,57 @@ dependencies = [ "libc", ] +[[package]] +name = "fdeflate" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "image" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-rational", + "num-traits", + "png", +] + [[package]] name = "itoa" version = "1.0.9" @@ -192,9 +338,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "linux-raw-sys" @@ -202,6 +348,68 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "png" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "proc-macro2" version = "1.0.67" @@ -235,7 +443,7 @@ version = "0.38.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" dependencies = [ - "bitflags", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", @@ -274,7 +482,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", ] [[package]] @@ -294,12 +502,35 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.37" @@ -327,6 +558,26 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "toml" version = "0.5.11" diff --git a/Cargo.toml b/Cargo.toml index 6a8f244..b36335d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,3 +19,5 @@ tee = "0.1.0" toml = "0.5.6" clap = { version = "4.0.15", features = ["derive", "wrap_help"] } shlex = "1.1.0" +image = { version = "0.24.7", default-features = false, features = ["png"] } +cytryna = { version = "0.1", default-features = false, features = ["smdh"], git = "https://github.com/Maccraft123/cytryna.git", rev = "ab2b9062d833911d87476f9e6cbb2cdb5517a579"} diff --git a/src/command.rs b/src/command.rs index 7ee7256..499ad35 100644 --- a/src/command.rs +++ b/src/command.rs @@ -349,7 +349,7 @@ impl Build { fn callback(&self, config: &Option) { if let Some(config) = config { eprintln!("Building smdh: {}", config.path_smdh().display()); - build_smdh(config, self.verbose); + build_smdh(config); eprintln!("Building 3dsx: {}", config.path_3dsx().display()); build_3dsx(config, self.verbose); diff --git a/src/lib.rs b/src/lib.rs index 8311048..e4534e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ use std::{env, io, process}; use cargo_metadata::{Message, MetadataCommand}; use command::{Input, Test}; +use cytryna::smdh::Smdh; use rustc_version::Channel; use semver::Version; use tee::TeeReader; @@ -229,15 +230,17 @@ pub fn get_metadata(messages: &[Message]) -> CTRConfig { let (package, artifact) = (package.unwrap(), artifact.unwrap()); - let mut icon = String::from("./icon.png"); + let mut icon_path = String::from("./icon.png"); - if !Path::new(&icon).exists() { - icon = format!( + if !Path::new(&icon_path).exists() { + icon_path = format!( "{}/libctru/default_icon.png", env::var("DEVKITPRO").unwrap() ); } + let icon = image::open(Path::new(&icon_path)).expect("Invalid PNG image"); + // for now assume a single "kind" since we only support one output artifact let name = match artifact.target.kind[0].as_ref() { "bin" | "lib" | "rlib" | "dylib" if artifact.target.test => { @@ -267,34 +270,16 @@ pub fn get_metadata(messages: &[Message]) -> CTRConfig { } } -/// Builds the smdh using `smdhtool`. -/// This will fail if `smdhtool` is not within the running directory or in a directory found in $PATH -pub fn build_smdh(config: &CTRConfig, verbose: bool) { - let mut command = Command::new("smdhtool"); - command - .arg("--create") - .arg(&config.name) - .arg(&config.description) - .arg(&config.author) - .arg(&config.icon) - .arg(config.path_smdh()) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()); - - if verbose { - print_command(&command); - } +/// Builds the smdh using `cytryna` library. +pub fn build_smdh(config: &CTRConfig) { + let smdh = Smdh::builder() + .with_short_desc(&config.name).unwrap() + .with_long_desc(&config.description).unwrap() + .with_publisher(&config.author).unwrap() + .with_icon((&config.icon).try_into().unwrap()) + .build().expect("SMDH building failed"); - let mut process = command - .spawn() - .expect("smdhtool command failed, most likely due to 'smdhtool' not being in $PATH"); - - let status = process.wait().unwrap(); - - if !status.success() { - process::exit(status.code().unwrap_or(1)); - } + std::fs::write(config.path_smdh(), smdh.as_bytes()).expect("Failed to write SMDH data"); } /// Builds the 3dsx using `3dsxtool`. @@ -396,7 +381,7 @@ pub struct CTRConfig { name: String, author: String, description: String, - icon: String, + icon: image::DynamicImage, target_path: PathBuf, cargo_manifest_path: PathBuf, }