refactor(windows): improve resource string parsing and documentation
- Rename structs to be more descriptive (IconRefStr, StrRefStr) - Add comprehensive documentation for all public items - Simplify error handling in FromStr implementations - Add getter methods for path and index fields
This commit is contained in:
@ -16,13 +16,16 @@ use windows_sys::Win32::UI::WindowsAndMessaging::HICON;
|
|||||||
|
|
||||||
// region: Icon Reference String
|
// region: Icon Reference String
|
||||||
|
|
||||||
|
/// Error occurs when given string is not a valid Icon Reference String.
|
||||||
#[derive(Debug, TeError)]
|
#[derive(Debug, TeError)]
|
||||||
#[error("given string \"{inner}\" is not a valid Icon Reference String")]
|
#[error("given string \"{inner}\" is not a valid Icon Reference String")]
|
||||||
pub struct ParseIconRcError {
|
pub struct ParseIconRefStrError {
|
||||||
|
/// The clone of string which is not a valid Icon Reference String
|
||||||
inner: String,
|
inner: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseIconRcError {
|
impl ParseIconRefStrError {
|
||||||
|
/// Create new error instance.
|
||||||
fn new(s: &str) -> Self {
|
fn new(s: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: s.to_string(),
|
inner: s.to_string(),
|
||||||
@ -30,19 +33,27 @@ impl ParseIconRcError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, TeError)]
|
/// The struct representing an Icon Reference String
|
||||||
#[error("fail to load icon")]
|
/// looks like `%SystemRoot%\System32\imageres.dll,-72`.
|
||||||
pub struct FetchIconError {}
|
pub struct IconRefStr {
|
||||||
|
/// The path part of this reference string.
|
||||||
pub struct IconRc {
|
/// And it can be expandable.
|
||||||
path: String,
|
path: String,
|
||||||
|
/// The index part of this reference string.
|
||||||
index: u32,
|
index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IconRc {
|
impl IconRefStr {
|
||||||
/// Create a new Icon Reference String.
|
/// Create a new Icon Reference String.
|
||||||
///
|
///
|
||||||
/// `path` is the path to the icon resource file and it can be Expand String.
|
/// `path` is the path to the icon resource file and it can be one of following types:
|
||||||
|
///
|
||||||
|
/// * Absolute path: `C:\Windows\System32\imageres.dll`
|
||||||
|
/// * Relative path: `imageres.dll`
|
||||||
|
/// * Expandable Path: `%SystemRoot%\System32\imageres.dll`
|
||||||
|
///
|
||||||
|
/// And it also can be quoted like: `"C:\Program Files\MyApp\MyApp.dll"`
|
||||||
|
///
|
||||||
/// `index` is the index of the icon in the resource file.
|
/// `index` is the index of the icon in the resource file.
|
||||||
pub fn new(path: &str, index: u32) -> Self {
|
pub fn new(path: &str, index: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -51,34 +62,41 @@ impl IconRc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_icon(&self) -> Result<Icon, FetchIconError> {
|
/// Get the path part of this reference string.
|
||||||
todo!()
|
///
|
||||||
|
/// This path can be absolute path, relative path or expandable path.
|
||||||
|
pub fn get_path(&self) -> &str {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the index part of this reference string.
|
||||||
|
pub fn get_index(&self) -> u32 {
|
||||||
|
self.index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for IconRc {
|
impl Display for IconRefStr {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "{},-{}", self.path, self.index)
|
write!(f, "{},-{}", self.path, self.index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for IconRc {
|
impl FromStr for IconRefStr {
|
||||||
type Err = ParseIconRcError;
|
type Err = ParseIconRefStrError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
static RE: LazyLock<Regex> =
|
static RE: LazyLock<Regex> =
|
||||||
LazyLock::new(|| Regex::new(r"^([^,@][^,]*),-([0-9]+)$").unwrap());
|
LazyLock::new(|| Regex::new(r"^([^,@].*),-([0-9]+)$").unwrap());
|
||||||
let caps = RE.captures(s);
|
let caps = RE.captures(s);
|
||||||
if let Some(caps) = caps {
|
if let Some(caps) = caps {
|
||||||
let path = &caps[1];
|
let path = &caps[1];
|
||||||
let index = caps.get(2).ok_or(ParseIconRcError::new(s)).and_then(|sv| {
|
let index = caps
|
||||||
sv.as_str()
|
.get(2)
|
||||||
.parse::<u32>()
|
.and_then(|sv| sv.as_str().parse::<u32>().ok())
|
||||||
.map_err(|_| ParseIconRcError::new(s))
|
.ok_or(ParseIconRefStrError::new(s))?;
|
||||||
})?;
|
|
||||||
Ok(Self::new(path, index))
|
Ok(Self::new(path, index))
|
||||||
} else {
|
} else {
|
||||||
Err(ParseIconRcError::new(s))
|
Err(ParseIconRefStrError::new(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,13 +105,16 @@ impl FromStr for IconRc {
|
|||||||
|
|
||||||
// region: String Reference String
|
// region: String Reference String
|
||||||
|
|
||||||
|
/// Error occurs when given string is not a valid String Reference String.
|
||||||
#[derive(Debug, TeError)]
|
#[derive(Debug, TeError)]
|
||||||
#[error("given string \"{inner}\" is not a valid String Reference String")]
|
#[error("given string \"{inner}\" is not a valid String Reference String")]
|
||||||
pub struct ParseStrRcError {
|
pub struct ParseStrRefStrError {
|
||||||
|
/// The clone of string which is not a valid String Reference String
|
||||||
inner: String,
|
inner: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseStrRcError {
|
impl ParseStrRefStrError {
|
||||||
|
/// Create new error instance.
|
||||||
fn new(s: &str) -> Self {
|
fn new(s: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: s.to_string(),
|
inner: s.to_string(),
|
||||||
@ -101,20 +122,22 @@ impl ParseStrRcError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, TeError)]
|
/// The struct representing an String Reference String
|
||||||
#[error("fail to load string")]
|
/// looks like `@%SystemRoot%\System32\shell32.dll,-30596`.
|
||||||
pub struct FetchStrError{}
|
pub struct StrRefStr {
|
||||||
|
/// The path part of this reference string.
|
||||||
pub struct StrRc {
|
/// And it can be expandable.
|
||||||
path: String,
|
path: String,
|
||||||
|
/// The index part of this reference string.
|
||||||
index: u32,
|
index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StrRc {
|
impl StrRefStr {
|
||||||
/// Create a new String Reference String.
|
/// Create a new Icon Reference String.
|
||||||
///
|
///
|
||||||
/// `path` is the path to the string resource file and it can be Expand String.
|
/// `path` is the path to the string resource file.
|
||||||
/// `index` is the index of the string in the resource file.
|
/// `index` is the index of the string in the resource file.
|
||||||
|
/// For the detail of these parameters, please see IconRefStr.
|
||||||
pub fn new(path: &str, index: u32) -> Self {
|
pub fn new(path: &str, index: u32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
path: path.to_string(),
|
path: path.to_string(),
|
||||||
@ -122,33 +145,40 @@ impl StrRc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_string(&self) -> Result<String, FetchStrError> {
|
/// Get the path part of this reference string.
|
||||||
todo!()
|
///
|
||||||
|
/// This path can be absolute path, relative path or expandable path.
|
||||||
|
pub fn get_path(&self) -> &str {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the index part of this reference string.
|
||||||
|
pub fn get_index(&self) -> u32 {
|
||||||
|
self.index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for StrRc {
|
impl Display for StrRefStr {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "@{},-{}", self.path, self.index)
|
write!(f, "@{},-{}", self.path, self.index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for StrRc {
|
impl FromStr for StrRefStr {
|
||||||
type Err = ParseStrRcError;
|
type Err = ParseStrRefStrError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^@([^,]+),-([0-9]+)$").unwrap());
|
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"^@(.+),-([0-9]+)$").unwrap());
|
||||||
let caps = RE.captures(s);
|
let caps = RE.captures(s);
|
||||||
if let Some(caps) = caps {
|
if let Some(caps) = caps {
|
||||||
let path = &caps[1];
|
let path = &caps[1];
|
||||||
let index = caps.get(2).ok_or(ParseStrRcError::new(s)).and_then(|sv| {
|
let index = caps
|
||||||
sv.as_str()
|
.get(2)
|
||||||
.parse::<u32>()
|
.and_then(|sv| sv.as_str().parse::<u32>().ok())
|
||||||
.map_err(|_| ParseStrRcError::new(s))
|
.ok_or(ParseStrRefStrError::new(s))?;
|
||||||
})?;
|
|
||||||
Ok(Self::new(path, index))
|
Ok(Self::new(path, index))
|
||||||
} else {
|
} else {
|
||||||
Err(ParseStrRcError::new(s))
|
Err(ParseStrRefStrError::new(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user