feat: update error notes for wfassoc

This commit is contained in:
2026-06-25 13:42:23 +08:00
parent 1a44240f88
commit 880f90211b
8 changed files with 58 additions and 47 deletions

View File

@@ -14,17 +14,17 @@ use wfassoc::highlevel::{Program, Schema};
#[derive(Debug, TeError)] #[derive(Debug, TeError)]
enum Error { enum Error {
/// Error when operating Schema. /// Error when operating Schema.
#[error("{0}")] #[error("wfassoc error: {0}")]
Schema(#[from] wfassoc::highlevel::SchemaError), Schema(#[from] wfassoc::highlevel::SchemaError),
/// Error when parsing Schema into Program. /// Error when parsing Schema into Program.
#[error("{0}")] #[error("wfassoc error: {0}")]
ParseProgram(#[from] wfassoc::highlevel::ParseProgramError), ParseProgram(#[from] wfassoc::highlevel::ParseProgramError),
/// Error when operating Program. /// Error when operating Program.
#[error("{0}")] #[error("wfassoc error: {0}")]
Program(#[from] wfassoc::highlevel::ProgramError), Program(#[from] wfassoc::highlevel::ProgramError),
/// Error when manipulating with C-style string. /// Error when manipulating with C-style string.
#[error("C-Style string FFI error:{0}")] #[error("C-Style string FFI error: {0}")]
CStrFfi(#[from] cstr_ffi::Error), CStrFfi(#[from] cstr_ffi::Error),
/// Error when manipulating with object pool. /// Error when manipulating with object pool.
#[error("object pool error: {0}")] #[error("object pool error: {0}")]

View File

@@ -63,7 +63,7 @@ impl Manifest {
#[derive(Debug, TeError)] #[derive(Debug, TeError)]
pub enum ParseSchemaError { pub enum ParseSchemaError {
/// Error when operating with schema. /// Error when operating with schema.
#[error("{0}")] #[error("failed on parsing manifest file to Schema: {0}")]
Schema(#[from] wfassoc::highlevel::SchemaError) Schema(#[from] wfassoc::highlevel::SchemaError)
} }

View File

@@ -12,20 +12,21 @@ use toml;
#[derive(Debug, TeError)] #[derive(Debug, TeError)]
pub enum Error { pub enum Error {
/// Error when parsing Manifest TOML file. /// Error when parsing Manifest TOML file.
#[error("{0}")] #[error("initialization error: {0}")]
ParseManifest(#[from] manifest::ParseManifestError), ParseManifest(#[from] manifest::ParseManifestError),
/// Error when parsing Manifest into Schema. /// Error when parsing Manifest into Schema.
#[error("{0}")] #[error("initialization error: {0}")]
ParseSchema(#[from] manifest::ParseSchemaError), ParseSchema(#[from] manifest::ParseSchemaError),
/// Error when serializing TOML
#[error("initialization error: {0}")]
SerializeToml(#[from] toml::ser::Error),
/// Error when parsing Schema into Program. /// Error when parsing Schema into Program.
#[error("{0}")] #[error("wfassoc error: {0}")]
ParseProgram(#[from] wfassoc::highlevel::ParseProgramError), ParseProgram(#[from] wfassoc::highlevel::ParseProgramError),
/// Error when operating Program. /// Error when operating Program.
#[error("{0}")] #[error("wfassoc error: {0}")]
Program(#[from] wfassoc::highlevel::ProgramError), Program(#[from] wfassoc::highlevel::ProgramError),
/// Error when serializing TOML
#[error("{0}")]
SerializeToml(#[from] toml::ser::Error),
/// Find duplicated name when converting extension name to index /// Find duplicated name when converting extension name to index
#[error("given extension name {0} has been specified more than one time")] #[error("given extension name {0} has been specified more than one time")]
@@ -35,7 +36,7 @@ pub enum Error {
BadExtName(String), BadExtName(String),
/// Find star (*) extension name with other extension names when converting extension name to index /// Find star (*) extension name with other extension names when converting extension name to index
#[error("wildcard extension name \"*\" is not allowed to be used with other extension names")] #[error("wildcard extension name \"*\" is not allowed to be used with other extension names")]
ExclusiveStarExtName(String), ExclusiveStarExtName,
} }
/// Result type used in this module. /// Result type used in this module.
@@ -60,7 +61,7 @@ fn stringified_exts_to_indices(
// Check for star (*) with other extensions // Check for star (*) with other extensions
let has_star = exts.iter().any(|ext| ext == "*"); let has_star = exts.iter().any(|ext| ext == "*");
if has_star && exts.len() > 1 { if has_star && exts.len() > 1 {
return Err(Error::ExclusiveStarExtName("*".to_string())); return Err(Error::ExclusiveStarExtName);
} }
// If star is present alone, return fixed list from zero to the maximum ext index. // If star is present alone, return fixed list from zero to the maximum ext index.

View File

@@ -17,37 +17,36 @@ use thiserror::Error as TeError;
/// Error occurs when trying converting [Schema] into [Program]. /// Error occurs when trying converting [Schema] into [Program].
#[derive(Debug, TeError)] #[derive(Debug, TeError)]
pub enum ParseProgramError { pub enum ParseProgramError {
#[error("{0}")] #[error("parsing into Program error: {0}")]
BadExtBody(#[from] concept::BadExtBodyError), BadExtBody(#[from] concept::BadExtBodyError),
#[error("{0}")] #[error("parsing into Program error: {0}")]
BadProgIdPart(#[from] concept::BadProgIdPartError), BadProgIdPart(#[from] concept::BadProgIdPartError),
#[error("{0}")] #[error("parsing into Program error: {0}")]
BadFileName(#[from] concept::BadFileNameError), BadFileName(#[from] concept::BadFileNameError),
#[error("{0}")] #[error("parsing into Program error: {0}")]
ParseCmdLine(#[from] concept::ParseCmdLineError), ParseCmdLine(#[from] concept::ParseCmdLineError),
#[error("{0}")] #[error("parsing into Program error: {0}")]
CastOsStr(#[from] utilities::CastOsStrError), CastOsStr(#[from] utilities::CastOsStrError),
#[error("given path doesn't has legal file name part")]
#[error("given path doesn't has legal file name part when parsing into Program")]
NoFileNamePart, NoFileNamePart,
#[error("given path doesn't has legal directory part")] #[error("given path doesn't has legal directory part when parsing into Program")]
NoDirNamePart, NoDirNamePart,
#[error("given identifier is not presented in dict")] #[error("identifier {0} is unexpected not presented in HashMap when parsing into Program")]
NoSuchIdentifier, NoSuchIdentifier(String),
#[error("extension name should not be empty")] #[error("bad program identifier found when parsing into Program")]
EmptyExtension,
#[error("given program identifier is not allowed")]
BadIdentifier, BadIdentifier,
} }
/// Error occurs when operating with [Program]. /// Error occurs when operating with [Program].
#[derive(Debug, TeError)] #[derive(Debug, TeError)]
pub enum ProgramError { pub enum ProgramError {
#[error("{0}")] #[error("Program operation error: {0}")]
Lowlevel(#[from] lowlevel::Error), Lowlevel(#[from] lowlevel::Error),
#[error("{0}")] #[error("Program operation error: {0}")]
LoadIconRc(#[from] concept::LoadIconRcError), LoadIconRc(#[from] concept::LoadIconRcError),
#[error("given index is invalid")] #[error("given file extension index {0} is invalid when visiting Program")]
BadIndex, BadIndex(usize),
} }
// endregion // endregion
@@ -129,7 +128,7 @@ impl Program {
.get(*index) .get(*index)
.expect("unexpected invalid index") .expect("unexpected invalid index")
.clone()), .clone()),
None => Err(ParseProgramError::NoSuchIdentifier), None => Err(ParseProgramError::NoSuchIdentifier(key.to_string())),
} }
} }
@@ -322,7 +321,10 @@ impl Program {
pub fn resolve_ext(&self, index: usize) -> Result<ProgramSelfExtStatus, ProgramError> { pub fn resolve_ext(&self, index: usize) -> Result<ProgramSelfExtStatus, ProgramError> {
// Fetch data // Fetch data
let progid_ext_key = self.ext_keys.get(index).ok_or(ProgramError::BadIndex)?; let progid_ext_key = self
.ext_keys
.get(index)
.ok_or(ProgramError::BadIndex(index))?;
// Try resolving name with string resource first, // Try resolving name with string resource first,
// and fallback to ProgId verbatim. // and fallback to ProgId verbatim.
@@ -507,7 +509,7 @@ impl Program {
ext_key.ensure(scope)?; ext_key.ensure(scope)?;
ext_key.set_default(scope, Some(progid_key.inner()))?; ext_key.set_default(scope, Some(progid_key.inner()))?;
} }
None => return Err(ProgramError::BadIndex), None => return Err(ProgramError::BadIndex(index)),
}; };
// Everything is okey. // Everything is okey.
@@ -529,7 +531,7 @@ impl Program {
ext_key.ensure(scope)?; ext_key.ensure(scope)?;
ext_key.set_default(scope, None)?; ext_key.set_default(scope, None)?;
} }
None => return Err(ProgramError::BadIndex), None => return Err(ProgramError::BadIndex(index)),
} }
// Everything is okey. // Everything is okey.
@@ -597,7 +599,7 @@ impl Program {
// Okey, return it. // Okey, return it.
Ok(Some(ProgramExtStatus::new(name, icon))) Ok(Some(ProgramExtStatus::new(name, icon)))
} }
None => Err(ProgramError::BadIndex), None => Err(ProgramError::BadIndex(index)),
} }
} }
} }

View File

@@ -7,7 +7,7 @@ use super::{Program, ParseProgramError};
/// Error occurs when operating with [Schema]. /// Error occurs when operating with [Schema].
#[derive(Debug, TeError)] #[derive(Debug, TeError)]
pub enum SchemaError { pub enum SchemaError {
#[error("duplicate key: {0}")] #[error("duplicate key in Schema operation: {0}")]
DuplicateKey(String), DuplicateKey(String),
} }

View File

@@ -10,27 +10,27 @@ use winreg::enums::{KEY_READ, KEY_WRITE};
/// Error occurs in this module. /// Error occurs in this module.
#[derive(Debug, TeError)] #[derive(Debug, TeError)]
pub enum Error { pub enum Error {
#[error("can not perform this operation because lack essential privilege")] #[error("some lowlevel operations require escalating privilege")]
NoPrivilege, NoPrivilege,
#[error("given registry key is inexistant")] #[error("given lowlevel registry key is not presented")]
InexistantKey, InexistantKey,
#[error("registry operation error: {0}")] #[error("lowlevel registry operation error: {0}")]
BadRegOp(#[from] std::io::Error), BadRegOp(#[from] std::io::Error),
#[error("{0}")] #[error("unexpected blank registry key in lowlevel registry operation")]
UnexpectedBlankKey(#[from] regext::BlankPathError), UnexpectedBlankKey(#[from] regext::BlankPathError),
#[error("{0}")] #[error("lowlevel operation error: {0}")]
ExpandEnvVar(#[from] concept::ExpandEnvVarError), ExpandEnvVar(#[from] concept::ExpandEnvVarError),
#[error("{0}")] #[error("lowlevel operation error: {0}")]
LoadIconRc(#[from] concept::LoadIconRcError), LoadIconRc(#[from] concept::LoadIconRcError),
#[error("{0}")] #[error("lowlevel operation error: {0}")]
LoadStrRc(#[from] concept::LoadStrRcError), LoadStrRc(#[from] concept::LoadStrRcError),
#[error("{0}")] #[error("lowlevel operation error: {0}")]
ParseVerb(#[from] concept::ParseVerbError), ParseVerb(#[from] concept::ParseVerbError),
#[error("{0}")] #[error("lowlevel operation error: {0}")]
ParseCmdLine(#[from] concept::ParseCmdLineError), ParseCmdLine(#[from] concept::ParseCmdLineError),
#[error("{0}")] #[error("lowlevel operation error: {0}")]
ParseExt(#[from] concept::ParseExtError), ParseExt(#[from] concept::ParseExtError),
} }

View File

@@ -9,7 +9,7 @@ use thiserror::Error as TeError;
/// The error occurs when casting `OsStr` into `str`. /// The error occurs when casting `OsStr` into `str`.
#[derive(Debug, TeError)] #[derive(Debug, TeError)]
#[error("fail to cast OS string into string")] #[error("fail to cast OS string into Rust string")]
pub struct CastOsStrError {} pub struct CastOsStrError {}
impl CastOsStrError { impl CastOsStrError {

View File

@@ -42,6 +42,8 @@ impl Ext {
/// Create an new file extension. /// Create an new file extension.
/// ///
/// `body` is the body of file extension (excluding dot, such as `jpg`). /// `body` is the body of file extension (excluding dot, such as `jpg`).
/// Empty body is not allowed.
///
/// If you want to create this struct with ordinary extension string like `.jpg`, /// If you want to create this struct with ordinary extension string like `.jpg`,
/// please use `Ext::from_str()` or `parse::<Ext>()` instead. /// please use `Ext::from_str()` or `parse::<Ext>()` instead.
pub fn new(body: &str) -> Result<Self, BadExtBodyError> { pub fn new(body: &str) -> Result<Self, BadExtBodyError> {
@@ -56,11 +58,17 @@ impl Ext {
} }
/// Get the body part of file extension (excluding dot) /// Get the body part of file extension (excluding dot)
///
/// This struct promise that there is no possibility that return value is blank
/// (i.e. the body of file extension is empty).
pub fn inner(&self) -> &str { pub fn inner(&self) -> &str {
&self.body &self.body
} }
/// Get the body part of file extension (with leading dot) /// Get the body part of file extension (with leading dot)
///
/// This struct promise that there is no possibility that return value is dot only
/// (i.e. the body of file extension is empty).
pub fn dotted_inner(&self) -> String { pub fn dotted_inner(&self) -> String {
// Reuse Display trait result // Reuse Display trait result
self.to_string() self.to_string()