diff --git a/wfassoc/src/lowlevel.rs b/wfassoc/src/lowlevel.rs index b47e29a..6970cc7 100644 --- a/wfassoc/src/lowlevel.rs +++ b/wfassoc/src/lowlevel.rs @@ -20,6 +20,10 @@ pub enum Error { BadRegOp(#[from] std::io::Error), #[error("{0}")] UnexpectedBlankKey(#[from] regext::BlankPathError), + #[error("{0}")] + LoadIconRc(#[from] concept::LoadIconRcError), + #[error("{0}")] + LoadStrRc(#[from] concept::LoadStrRcError), } // endregion @@ -99,8 +103,8 @@ pub enum LosseProgId { impl Display for LosseProgId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - LosseProgId::Plain(v) => write!(f, "{}", v), - LosseProgId::Strict(v) => write!(f, "{}", v), + LosseProgId::Plain(v) => v.fmt(f), + LosseProgId::Strict(v) => v.fmt(f), } } } @@ -125,6 +129,115 @@ impl From for LosseProgId { // endregion +// region: Losse Icon Reference String + +/// The enum representing a losse Icon Reference String. +/// +/// In real usage, programmer can use Icon Reference String, +/// or a plain string pointing to a icon file as the icon setting value. +/// This enum is designed for handling this scenario. +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum LosseIconRefStr { + Plain(String), + Strict(concept::IconRefStr), +} + +impl LosseIconRefStr { + pub fn extract(&self, kind: concept::IconSizeKind) -> Result { + let rc = match self { + LosseIconRefStr::Plain(v) => concept::IconRc::with_ico_file(v.as_str(), kind)?, + LosseIconRefStr::Strict(v) => concept::IconRc::new(v.get_path(), v.get_index(), kind)?, + }; + Ok(rc) + } +} + +impl Display for LosseIconRefStr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + LosseIconRefStr::Plain(v) => v.fmt(f), + LosseIconRefStr::Strict(v) => v.fmt(f), + } + } +} + +impl From<&str> for LosseIconRefStr { + fn from(s: &str) -> Self { + // match it for standard IconRefStr first + if let Ok(v) = concept::IconRefStr::from_str(s) { + Self::Strict(v) + } else { + // fallback with other + Self::Plain(s.to_string()) + } + } +} + +impl From for LosseIconRefStr { + fn from(value: concept::IconRefStr) -> Self { + Self::Strict(value) + } +} + +// endregion + +// region: Losse String Reference String + +/// The enum representing a losse String Reference String. +/// +/// In real usage, programmer can use String Reference String, +/// or a plain string as the string setting value. +/// This enum is designed for handling this scenario. +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum LosseStrRefStr { + Plain(String), + Strict(concept::StrRefStr), +} + +impl LosseStrRefStr { + pub fn extract(&self) -> Result { + let rv = match self { + // For plain string, we just simply clone it. + LosseStrRefStr::Plain(v) => v.clone(), + // For string reference string, we try to resolve it. + LosseStrRefStr::Strict(v) => { + let rc = concept::StrRc::new(v.get_path(), v.get_index())?; + rc.into_string() + }, + }; + Ok(rv) + } +} + +impl Display for LosseStrRefStr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + LosseStrRefStr::Plain(v) => v.fmt(f), + LosseStrRefStr::Strict(v) => v.fmt(f), + } + } +} + +impl From<&str> for LosseStrRefStr { + fn from(s: &str) -> Self { + // match it for standard StrRefStr first + if let Ok(v) = concept::StrRefStr::from_str(s) { + Self::Strict(v) + } else { + // fallback with other + Self::Plain(s.to_string()) + } + } +} + +impl From for LosseStrRefStr { + fn from(value: concept::StrRefStr) -> Self { + Self::Strict(value) + } +} + +// endregion + // endregion // region: Utilities diff --git a/wfassoc/src/win32/concept.rs b/wfassoc/src/win32/concept.rs index 8821997..0f318aa 100644 --- a/wfassoc/src/win32/concept.rs +++ b/wfassoc/src/win32/concept.rs @@ -650,6 +650,10 @@ impl StrRc { pub fn get_string(&self) -> &str { &self.inner } + + pub fn into_string(self) -> String { + self.inner + } } // endregion