From 60962650170a6950cecca8de5b3b8f900bdc58f6 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Thu, 30 Apr 2026 12:59:37 +0800 Subject: [PATCH] feat: add placeholder cmdline concept --- wfassoc/src/win32/concept.rs | 69 ++++++++++++++++++++++++++++++++++++ wfassoc/tests/concept.rs | 23 ++++++++++++ 2 files changed, 92 insertions(+) diff --git a/wfassoc/src/win32/concept.rs b/wfassoc/src/win32/concept.rs index 0f318aa..556e1a3 100644 --- a/wfassoc/src/win32/concept.rs +++ b/wfassoc/src/win32/concept.rs @@ -916,3 +916,72 @@ impl FromStr for Verb { } // endregion + +// region: Command Line + +/// The error occurs when constructing CmdLine with bad arguments. +#[derive(Debug, TeError)] +#[error("given file extension body \"{inner}\" is invalid")] +pub struct BadCmdLineError { + inner: String, +} + +/// The struct representing a Windows command line. +/// +/// # Note +/// +/// This struct currently does nothing for validation for given command line. +/// Because there is no standard for validating this. +/// So I just write this struct as a placeholder for future extension. +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct CmdLine { + inner: Vec, +} + +impl CmdLine { + /// Create a new command line. + pub fn new>(args: &[S]) -> Result { + Ok(Self { inner: args.iter().map(|s| s.as_ref().to_string()).collect() }) + } + + /// Get the full command line. + pub fn full(&self) -> String { + self.inner.join(" ") + } + + /// Get the iterator of command line arguments. + pub fn iter(&self) -> impl Iterator { + self.inner.iter().map(|s| s.as_str()) + } +} + +/// The error occurs when constructing CmdLine with bad syntax. +#[derive(Debug, TeError)] +#[error("given command line \"{inner}\" is invalid")] +pub struct ParseCmdLineError { + inner: String, +} + +impl ParseCmdLineError { + fn new(inner: &str) -> Self { + Self { + inner: inner.to_string(), + } + } +} + +impl Display for CmdLine { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.full()) + } +} + +impl FromStr for CmdLine { + type Err = ParseCmdLineError; + + fn from_str(s: &str) -> Result { + // We simply split it by space for rough result. + Ok(Self { inner: s.split(' ').map(|s| s.to_string()).collect() }) + } +} + diff --git a/wfassoc/tests/concept.rs b/wfassoc/tests/concept.rs index 7011862..aed579e 100644 --- a/wfassoc/tests/concept.rs +++ b/wfassoc/tests/concept.rs @@ -276,3 +276,26 @@ fn test_verb() { } // endregion + +// region: Command Line + +#[test] +fn test_cmd_line() { + fn ok_tester(s: &str) { + let rv = CmdLine::from_str(s); + assert!(rv.is_ok()); + // let rv = rv.unwrap(); + // assert_eq!(s, rv.full()); + } + fn err_tester(s: &str) { + let rv = CmdLine::from_str(s); + assert!(rv.is_err()); + } + + ok_tester("notepad.exe"); + ok_tester("calc.exe /c"); + ok_tester("unix-like.exe -i some.file --option"); + // err_tester(""); +} + +// endregion