diff --git a/registry/Cargo.lock b/registry/Cargo.lock index 58896fbf..1c988da0 100644 --- a/registry/Cargo.lock +++ b/registry/Cargo.lock @@ -47,7 +47,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -57,15 +57,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "base62" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10e52a7bcb1d6beebee21fb5053af9e3cbb7a7ed1a4909e534040e676437ab1f" +dependencies = [ + "rustversion", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -78,6 +93,16 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bstr" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -130,6 +155,31 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crossterm" version = "0.28.1" @@ -161,16 +211,82 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" dependencies = [ + "cfg-if", "libc", - "windows-sys", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets", +] + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "globset" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", ] +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "heck" version = "0.5.0" @@ -183,12 +299,47 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "ignore" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata 0.4.7", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "indexmap" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -203,9 +354,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libyml" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64804cc6a5042d4f05379909ba25b503ec04e2c082151d62122d5dcaa274b961" [[package]] name = "linux-raw-sys" @@ -253,8 +410,17 @@ dependencies = [ "hermit-abi", "libc", "log", - "wasi", - "windows-sys", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "normpath" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" +dependencies = [ + "windows-sys 0.59.0", ] [[package]] @@ -386,6 +552,7 @@ dependencies = [ "clap", "crossterm", "registry 1.2.3", + "rust-i18n", "schemars", "serde", "serde_json", @@ -409,25 +576,94 @@ dependencies = [ "winapi", ] +[[package]] +name = "rust-i18n" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039f57d22229db401af3458ca939300178e99e88b938573cea12b7c2b0f09724" +dependencies = [ + "globwalk", + "once_cell", + "regex", + "rust-i18n-macro", + "rust-i18n-support", + "smallvec", +] + +[[package]] +name = "rust-i18n-macro" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde5c022360a2e54477882843d56b6f9bcb4bc62f504b651a2f497f0028d174f" +dependencies = [ + "glob", + "once_cell", + "proc-macro2", + "quote", + "rust-i18n-support", + "serde", + "serde_json", + "serde_yml", + "syn", +] + +[[package]] +name = "rust-i18n-support" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75d2844d36f62b5d6b66f9cf8f8cbdbbbdcdb5fd37a473a9cc2fb45fdcf485d2" +dependencies = [ + "arc-swap", + "base62", + "globwalk", + "itertools", + "lazy_static", + "normpath", + "once_cell", + "proc-macro2", + "regex", + "serde", + "serde_json", + "serde_yml", + "siphasher", + "toml", + "triomphe", +] + [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schemars" version = "0.8.21" @@ -501,6 +737,32 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_yml" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e76bab63c3fd98d27c17f9cbce177f64a91f5e69ac04cafe04e1bb25d1dc3c" +dependencies = [ + "indexmap", + "itoa", + "libyml", + "log", + "memchr", + "ryu", + "serde", + "serde_json", + "tempfile", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -540,12 +802,24 @@ dependencies = [ "libc", ] +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_vcruntime" version = "2.0.0" @@ -569,6 +843,20 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" +dependencies = [ + "cfg-if", + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "thiserror" version = "1.0.64" @@ -599,6 +887,40 @@ dependencies = [ "once_cell", ] +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.40" @@ -673,6 +995,17 @@ dependencies = [ "tracing-serde", ] +[[package]] +name = "triomphe" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" +dependencies = [ + "arc-swap", + "serde", + "stable_deref_trait", +] + [[package]] name = "unicode-ident" version = "1.0.13" @@ -697,12 +1030,31 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "winapi" version = "0.3.9" @@ -719,6 +1071,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -734,6 +1095,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -797,3 +1167,21 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.6.0", +] diff --git a/registry/Cargo.toml b/registry/Cargo.toml index b8c8a8f6..22d1e053 100644 --- a/registry/Cargo.toml +++ b/registry/Cargo.toml @@ -3,6 +3,11 @@ name = "registry" version = "1.0.0" edition = "2021" +[package.metadata.i18n] +available-locales = ["en-us"] +default-locale = "en-us" +load-path = "locales" + [profile.release] strip = true # optimize for size @@ -14,6 +19,7 @@ lto = true clap = { version = "4.5", features = ["derive"] } crossterm = "0.28" registry = "1.2" +rust-i18n = "3" schemars = "0.8" serde = "1.0" serde_json = "1.0" diff --git a/registry/locales/en-us.toml b/registry/locales/en-us.toml new file mode 100644 index 00000000..20414bf9 --- /dev/null +++ b/registry/locales/en-us.toml @@ -0,0 +1,52 @@ +_version = 1 + +[args] +about = "Manage state of Windows registry" +configAbout = "Manage registry configuration." +configArgsInputHelp = "The registry JSON input." +configArgsWhatIfHelp = "Run as a what-if operation instead of applying the registry configuration." +configGetAbout = "Retrieve registry configuration." +configSetAbout = "Apply registry configuration." +configDeleteAbout = "Delete registry configuration." +queryAbout = "Query a registry key or value." +queryArgsKeyPathHelp = "The registry key path to query." +queryArgsValueNameHelp = "The name of the value to query." +queryArgsRecurseHelp = "Recursively query subkeys." +setAbout = "Set a registry key or value." +setArgsKeyPathHelp = "The registry key path to set." +setArgsValueHelp = "The value to set." +removeAbout = "Remove a registry key or value." +removeArgsKeyPathHelp = "The registry key path to remove." +removeArgsValueNameHelp = "The name of the value to remove." +removeArgsRecurseHelp = "Recursively remove subkeys." +findAbout = "Find a registry key or value." +findArgsKeyPathHelp = "The registry key path to start find." +findArgsFindHelp = "The string to find." +findArgsRecurseHelp = "Recursively find." +findArgsKeysOnlyHelp = "Only find keys." +findArgsValuesOnlyHelp = "Only find values." +schemaAbout = "Retrieve JSON schema." + +[config] +# No localizable strings + +[error] +invalidHive = "Invalid hive" +json = "JSON" +registry = "Registry" +registryKey = "Registry key" +registryKeyNotFound = "Registry key not found" +registryValue = "Registry value" +utf16Conversion = "UTF-16 conversion failed due to interior NULL values for" +unsupportedValueDataType = "Unsupported registry value data type" + +[main] +tracingInitError = "Unable to set global default tracing subscriber. Tracing is diabled." +debugAttach = "attach debugger to pid %{pid} and press any key to continue" +debugEventReadError = "Error: Failed to read event: %{err}" +debugEventUnexpectedError = "Unexpected event: %{e:?}" + +[registry_helper] +whatIfCreateKey = "key: %{subkey} not found, would create it" +removeErrorKeyNotExist = "Key already does not exist" +removeDeletingSubKey = "Deleting subkey '%{name}' using %{parent}" diff --git a/registry/src/args.rs b/registry/src/args.rs index a0521ec9..8da9a8cd 100644 --- a/registry/src/args.rs +++ b/registry/src/args.rs @@ -2,9 +2,10 @@ // Licensed under the MIT License. use clap::{Parser, Subcommand}; +use rust_i18n::t; #[derive(Parser)] -#[clap(name = "registry", version = "0.0.1", about = "Manage state of Windows registry", long_about = None)] +#[clap(name = "registry", version = "0.0.1", about = t!("args.about").to_string(), long_about = None)] pub struct Arguments { #[clap(subcommand)] @@ -13,70 +14,70 @@ pub struct Arguments { #[derive(Debug, PartialEq, Eq, Subcommand)] pub enum ConfigSubCommand { - #[clap(name = "get", about = "Retrieve registry configuration.")] + #[clap(name = "get", about = t!("args.configGetAbout").to_string())] Get { - #[clap(short, long, required = true, help = "The registry JSON input.")] + #[clap(short, long, required = true, help = t!("args.configArgsInputHelp").to_string())] input: String, }, - #[clap(name = "set", about = "Apply registry configuration.")] + #[clap(name = "set", about = t!("args.configSetAbout").to_string())] Set { - #[clap(short, long, required = true, help = "The registry JSON input.")] + #[clap(short, long, required = true, help = t!("args.configArgsInputHelp").to_string())] input: String, - #[clap(short = 'w', long, help = "Run as a what-if operation instead of applying the registry configuration")] + #[clap(short = 'w', long, help = t!("args.configArgsWhatIfHelp").to_string())] what_if: bool, }, - #[clap(name = "delete", about = "Delete registry configuration.")] + #[clap(name = "delete", about = t!("args.configDeleteAbout").to_string())] Delete { - #[clap(short, long, required = true, help = "The registry JSON input.")] + #[clap(short, long, required = true, help = t!("args.configArgsInputHelp").to_string())] input: String, }, } #[derive(Debug, PartialEq, Eq, Subcommand)] pub enum SubCommand { - #[clap(name = "query", about = "Query a registry key or value.", arg_required_else_help = true)] + #[clap(name = "query", about = t!("args.queryAbout").to_string(), arg_required_else_help = true)] Query { - #[clap(short, long, required = true, help = "The registry key path to query.")] + #[clap(short, long, required = true, help = t!("args.queryArgsKeyPathHelp").to_string())] key_path: String, - #[clap(short, long, help = "The name of the value to query.")] + #[clap(short, long, help = t!("args.queryArgsValueNameHelp").to_string())] value_name: Option, - #[clap(short, long, help = "Recursively query subkeys.")] + #[clap(short, long, help = t!("args.queryArgsRecurseHelp").to_string())] recurse: bool, }, - #[clap(name = "set", about = "Set a registry key or value.")] + #[clap(name = "set", about = t!("args.setAbout").to_string())] Set { - #[clap(short, long, required = true, help = "The registry key path to set.")] + #[clap(short, long, required = true, help = t!("args.setArgsKeyPathHelp").to_string())] key_path: String, - #[clap(short, long, help = "The value to set.")] + #[clap(short, long, help = t!("args.setArgsValueHelp").to_string())] value: String, }, - #[clap(name = "remove", about = "Remove a registry key or value.", arg_required_else_help = true)] + #[clap(name = "remove", about = t!("args.removeAbout").to_string(), arg_required_else_help = true)] Remove { - #[clap(short, long, required = true, help = "The registry key path to remove.")] + #[clap(short, long, required = true, help = t!("args.removeArgsKeyPathHelp").to_string())] key_path: String, - #[clap(short, long, help = "The name of the value to remove.")] + #[clap(short, long, help = t!("args.removeArgsValueNameHelp").to_string())] value_name: Option, - #[clap(short, long, help = "Recursively remove subkeys.")] + #[clap(short, long, help = t!("args.removeArgsRecurseHelp").to_string())] recurse: bool, }, - #[clap(name = "find", about = "Find a registry key or value.", arg_required_else_help = true)] + #[clap(name = "find", about = t!("args.findAbout").to_string(), arg_required_else_help = true)] Find { - #[clap(short, long, required = true, help = "The registry key path to start find.")] + #[clap(short, long, required = true, help = t!("args.findArgsKeyPathHelp").to_string())] key_path: String, - #[clap(short, long, required = true, help = "The string to find.")] + #[clap(short, long, required = true, help = t!("args.findArgsFindHelp").to_string())] find: String, - #[clap(short, long, help = "Recursively find.")] + #[clap(short, long, help = t!("args.findArgsRecurseHelp").to_string())] recurse: bool, - #[clap(long, help = "Only find keys.")] + #[clap(long, help = t!("args.findArgsKeysOnlyHelp").to_string())] keys_only: bool, - #[clap(long, help = "Only find values.")] + #[clap(long, help = t!("args.findArgsValuesOnlyHelp").to_string())] values_only: bool, }, - #[clap(name = "config", about = "Manage registry configuration.", arg_required_else_help = true)] + #[clap(name = "config", about = t!("args.configAbout").to_string(), arg_required_else_help = true)] Config { #[clap(subcommand)] subcommand: ConfigSubCommand, }, - #[clap(name = "schema", about = "Retrieve JSON schema.")] + #[clap(name = "schema", about = t!("args.schemaAbout").to_string())] Schema, } diff --git a/registry/src/error.rs b/registry/src/error.rs index 0c768fbf..1e171a70 100644 --- a/registry/src/error.rs +++ b/registry/src/error.rs @@ -1,32 +1,33 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use rust_i18n::t; use thiserror::Error; #[derive(Error, Debug)] #[allow(clippy::module_name_repetitions)] pub enum RegistryError { - #[error("Invalid hive: {0}.")] + #[error("{t}: {0}", t = t!("error.invalidHive"))] InvalidHive(String), - #[error("JSON: {0}")] + #[error("{t}: {0}", t = t!("error.json"))] Json(#[from] serde_json::Error), - #[error("Registry: {0}")] + #[error("{t}: {0}", t = t!("error.registry"))] Registry(#[from] registry::Error), - #[error("Registry key: {0}")] + #[error("{t}: {0}", t = t!("error.registryKey"))] RegistryKey(#[from] registry::key::Error), - #[error("Registry key not found: {0}")] + #[error("{t}: {0}", t = t!("error.registryKeyNotFound"))] RegistryKeyNotFound(String), - #[error("Registry value: {0}")] + #[error("{t}: {0}", t = t!("error.registryValue"))] RegistryValue(#[from] registry::value::Error), - #[error("UTF-16 conversion of {0} failed due to interior NULL values")] + #[error("{t}: {0}", t = t!("error.utf16Conversion"))] Utf16Conversion(String), - #[error("Unsupported registry value data type")] + #[error("{t}", t = t!("error.unsupportedValueDataType"))] UnsupportedValueDataType, } diff --git a/registry/src/main.rs b/registry/src/main.rs index 7b078d79..5ef3ce7c 100644 --- a/registry/src/main.rs +++ b/registry/src/main.rs @@ -6,6 +6,10 @@ use crossterm::event; #[cfg(debug_assertions)] use std::env; +// Init translations +use rust_i18n::t; +rust_i18n::i18n!("locales", fallback = "en-us"); + use args::Arguments; use clap::Parser; use registry_helper::RegistryHelper; @@ -135,19 +139,20 @@ pub fn enable_tracing() { let subscriber = tracing_subscriber::Registry::default().with(fmt).with(filter); if tracing::subscriber::set_global_default(subscriber).is_err() { - eprintln!("Unable to set global default tracing subscriber. Tracing is diabled."); + eprintln!("{}", t!("main.tracingInitError")); } } #[cfg(debug_assertions)] fn check_debug() { if env::var("DEBUG_REGISTRY").is_ok() { - eprintln!("attach debugger to pid {} and press any key to continue", std::process::id()); + eprintln!("{}", t!("main.debugAttach", pid = std::process::id())); + loop { let event = match event::read() { Ok(event) => event, Err(err) => { - eprintln!("Error: Failed to read event: {err}"); + eprintln!("{}", t!("main.debugEventReadError", "err" => err)); break; } }; @@ -157,7 +162,7 @@ fn check_debug() { break; } } else { - eprintln!("Unexpected event: {event:?}"); + eprintln!("{}", t!("main.debugEventUnexpectedError", e = event : {:?})); continue; } } diff --git a/registry/src/registry_helper.rs b/registry/src/registry_helper.rs index e7975a1b..71adbedb 100644 --- a/registry/src/registry_helper.rs +++ b/registry/src/registry_helper.rs @@ -2,6 +2,7 @@ // Licensed under the MIT License. use registry::{Data, Hive, RegKey, Security, key, value}; +use rust_i18n::t; use utfx::{U16CString, UCString}; use crate::config::{Metadata, Registry, RegistryValueData}; use crate::error::RegistryError; @@ -99,7 +100,7 @@ impl RegistryHelper { }; if self.what_if { - what_if_metadata.push(format!("key: {subkey} not found, would create it")); + what_if_metadata.push(t!("registry_helper.whatIfCreateKey", "subkey" => subkey).to_string()); } else { reg_key = reg_key.create(path, Security::CreateSubKey)?; @@ -185,7 +186,7 @@ impl RegistryHelper { Ok(reg_key) => reg_key, // handle NotFound error Err(RegistryError::RegistryKeyNotFound(_)) => { - eprintln!("Key already does not exist"); + eprintln!("{}", t!("registry_helper.removeErrorKeyNotExist")); return Ok(()); }, Err(e) => return Err(e), @@ -200,7 +201,8 @@ impl RegistryHelper { // get the subkey name let subkey_name = &self.config.key_path[parent_path.len() + 1..]; - eprintln!("Deleting subkey '{subkey_name}' using {parent_reg_key}"); + + eprintln!("{}", t!("registry_helper.removeDeletingSubKey", name = subkey_name, parent = parent_reg_key)); let Ok(subkey_name) = UCString::::from_str(subkey_name) else { return Err(RegistryError::Utf16Conversion("subkey_name".to_string())); };