From 4d679588f8387e92b87d65dbd51c9821324f5e33 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Tue, 28 Oct 2025 12:50:15 +0800 Subject: [PATCH] feat(wfassoc): enhance CLSID handling and parsing - Add `getrandom` dependency for UUID v4 feature - Enable UUID v4 feature in `Cargo.toml` - Implement `Clsid::with_random()` for generating random CLSIDs - Improve `Clsid::new()` to accept `&Uuid` directly - Update `Clsid::from_str()` to use `uuid::fmt::Braced` for stricter parsing - Add comprehensive tests for valid and invalid CLSID strings - Fix minor typo in test assertion code - Enhance documentation comments for CLSID struct and error type --- Cargo.lock | 1 + wfassoc/Cargo.toml | 2 +- wfassoc/src/extra/windows.rs | 21 ++++++++++++++------- wfassoc/tests/extra_windows.rs | 17 ++++++++++++++--- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce95fca..b915cde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,6 +674,7 @@ version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ + "getrandom", "js-sys", "wasm-bindgen", ] diff --git a/wfassoc/Cargo.toml b/wfassoc/Cargo.toml index b07584d..edc7eaf 100644 --- a/wfassoc/Cargo.toml +++ b/wfassoc/Cargo.toml @@ -22,4 +22,4 @@ widestring = "1.2.1" indexmap = "2.11.4" itertools = "0.14.0" regex = "1.11.3" -uuid = "1.18.1" +uuid = { version = "1.18.1", features = ["v4"] } diff --git a/wfassoc/src/extra/windows.rs b/wfassoc/src/extra/windows.rs index da7d97b..7b3fa63 100644 --- a/wfassoc/src/extra/windows.rs +++ b/wfassoc/src/extra/windows.rs @@ -232,23 +232,31 @@ impl FromStr for ProgId { // region: CLSID +/// The struct representing Windows CLSID looks like +/// `{26EE0668-A00A-44D7-9371-BEB064C98683}` (case insensitive). +/// The brace is essential part. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Clsid { inner: Uuid, } impl Clsid { - pub fn new(uuid: &str) -> Result { - Self::from_str(uuid) + /// Create new CLSID from underlying UUID. + fn new(uuid: &Uuid) -> Self { + Self { inner: *uuid } } - // TODO: May add CLSID generator in there. + /// Create new random CLSID. + pub fn with_random() -> Self { + Self::new(&Uuid::new_v4()) + } } -/// The error occurs when parsing CLSID +/// The error occurs when parsing CLSID. #[derive(Debug, TeError)] #[error("given string \"{inner}\" is invalid for uuid")] pub struct ParseClsidError { + /// The clone of string which is not a valid CLSID. inner: String, } @@ -264,9 +272,8 @@ impl FromStr for Clsid { type Err = ParseClsidError; fn from_str(s: &str) -> Result { - Ok(Self { - inner: Uuid::parse_str(s).map_err(|_| ParseClsidError::new(s))?, - }) + let brace_uuid = uuid::fmt::Braced::from_str(s).map_err(|_| ParseClsidError::new(s))?; + Ok(Self::new(brace_uuid.as_uuid())) } } diff --git a/wfassoc/tests/extra_windows.rs b/wfassoc/tests/extra_windows.rs index ee02400..0c897d1 100644 --- a/wfassoc/tests/extra_windows.rs +++ b/wfassoc/tests/extra_windows.rs @@ -62,7 +62,7 @@ fn test_prog_id_parse() { fn ok_tester(s: &str, probe_vendor: &str, probe_component: &str, probe_version: Option) { let rv = ProgId::from_str(s); assert!(rv.is_ok()); - let rv =rv.unwrap(); + let rv = rv.unwrap(); assert_eq!(rv.get_vendor(), probe_vendor); assert_eq!(rv.get_component(), probe_component); assert_eq!(rv.get_version(), probe_version); @@ -81,8 +81,19 @@ fn test_prog_id_parse() { #[test] fn test_clsid() { - fn ok_tester(s: &str) {} - fn err_tester(s: &str) {} + fn ok_tester(s: &str) { + let rv = Clsid::from_str(s); + assert!(rv.is_ok()); + } + fn err_tester(s: &str) { + let rv = Clsid::from_str(s); + assert!(rv.is_err()); + } + + ok_tester("{59031a47-3f72-44a7-89c5-5595fe6b30ee}"); + ok_tester("{26EE0668-A00A-44D7-9371-BEB064C98683}"); + err_tester("26EE0668-A00A-44D7-9371-BEB064C98683"); + err_tester("{26EE0668A00A-44D7-9371-BEB064C98683}"); } #[test]