doc: add docstring for highlevel functions

This commit is contained in:
2026-06-26 14:40:01 +08:00
parent a350a591ad
commit db69452213
3 changed files with 86 additions and 3 deletions

View File

@@ -24,6 +24,8 @@ pub enum ParseProgramError {
#[error("parsing into Program error: {0}")]
BadFileName(#[from] concept::BadFileNameError),
#[error("parsing into Program error: {0}")]
ParseClsid(#[from] concept::ParseClsidError),
#[error("parsing into Program error: {0}")]
ParseCmdLine(#[from] concept::ParseCmdLineError),
#[error("parsing into Program error: {0}")]
CastOsStr(#[from] utilities::CastOsStrError),
@@ -61,6 +63,11 @@ pub struct Program {
app_path: String,
app_file_name: String,
app_dir_path: String,
// TODO: Remove this dead_code attribute once we start to use CLSID.
#[allow(dead_code)]
clsid: concept::Clsid,
name: Option<Arc<ProgramStr>>,
icon: Option<Arc<ProgramIcon>>,
behavior: Option<Arc<ProgramBehavior>>,
@@ -102,6 +109,8 @@ impl Program {
.ok_or(ParseProgramError::NoDirNamePart)
}
/// Flatten a `HashMap<String, V>` into a `Vec<U>` with a reverse index map,
/// by applying the given transformation function `f` to each value.
fn flat_hashmap<V, U, F>(
hashmap: &HashMap<String, V>,
f: F,
@@ -118,6 +127,8 @@ impl Program {
Ok((vector, indexmap))
}
/// Resolve a key string to an `Arc<T>` by looking it up in the index map,
/// then indexing into the vector.
fn resolve_index<T>(
key: &str,
vector: &Vec<Arc<T>>,
@@ -175,6 +186,9 @@ impl Program {
let app_paths_key = lowlevel::AppPathsKey::new(key.clone());
let applications_key = lowlevel::ApplicationsKey::new(key.clone());
// Parse CLSID
let clsid = schema.get_clsid().parse::<concept::Clsid>()?;
// Build string, icon and behavior list,
// and build mapper at the same time.
let (strs, strs_index_map) = Self::flat_hashmap(schema.get_strs(), |entry| {
@@ -259,6 +273,7 @@ impl Program {
app_path,
app_file_name,
app_dir_path,
clsid,
name,
icon,
behavior,
@@ -272,6 +287,10 @@ impl Program {
}
impl Program {
/// Resolve the display name of this application.
///
/// Returns the user-specified display name first.
/// Falls back to the executable file name if no display name is configured.
pub fn resolve_name(&self) -> Result<String, ProgramError> {
// Fecch from user specified name first
let name = self
@@ -290,6 +309,10 @@ impl Program {
Ok(self.app_file_name.clone())
}
/// Resolve the icon of this application.
///
/// Returns the user-specified icon first, then falls back to the first icon from the executable,
/// and finally to the system default executable icon.
pub fn resolve_icon(&self) -> Result<concept::IconRc, ProgramError> {
// Fetch from user specified icon first
let icon = self
@@ -311,14 +334,23 @@ impl Program {
)?)
}
/// Return the number of file extensions associated with this program.
pub fn exts_len(&self) -> usize {
self.ext_keys.len()
}
/// Find the index of a file extension by its body (without leading dot).
///
/// Returns `None` if the given extension is not associated with this program.
pub fn find_ext(&self, body: &str) -> Option<usize> {
self.ext_keys_map.get(body).copied()
}
/// Resolve the extension status for the extension at the given index.
/// This status including the ProgId associated with this file extension,
/// and the display name and icon for this file extension.
///
/// Returns the fetched status, or the error occurs when fetching.
pub fn resolve_ext(&self, index: usize) -> Result<ProgramSelfExtStatus, ProgramError> {
// Fetch data
let progid_ext_key = self
@@ -461,8 +493,7 @@ impl Program {
/// Check whether this application has been registered in given view.
///
/// Please note that this is a rough check and do not validate any data.
///
/// The return value only ensures the pre-requirement of `register` and `unregister`.
/// The return value only ensures the pre-requirements of [Self::register] and [Self::unregister].
pub fn is_registered(&self, scope: Scope) -> Result<bool, ProgramError> {
// Check App Paths subkey.
debug_println!("Checking App Paths subkey...");
@@ -494,6 +525,7 @@ impl Program {
Ok(true)
}
/// Set this program as the default handler for the file extension at the given index.
pub fn link_ext(&mut self, scope: Scope, index: usize) -> Result<(), ProgramError> {
match self.ext_keys.get_mut(index) {
Some(program_key) => {
@@ -518,6 +550,7 @@ impl Program {
Ok(())
}
/// Remove this program as the default handler for the file extension at the given index.
pub fn unlink_ext(&mut self, scope: Scope, index: usize) -> Result<(), ProgramError> {
match self.ext_keys.get_mut(index) {
Some(program_key) => {
@@ -540,6 +573,10 @@ impl Program {
Ok(())
}
/// Query the current default association for the file extension at the given index.
///
/// Returns `Ok(None)` if the extension is not associated with any program,
/// or if the associated program's registration data is missing.
pub fn query_ext(
&self,
view: View,
@@ -655,6 +692,7 @@ pub struct ProgramSelfExtStatus {
}
impl ProgramSelfExtStatus {
/// Create a new `ProgramSelfExtStatus`.
fn new(ext: concept::Ext, name: String, icon: concept::IconRc) -> Self {
Self { ext, name, icon }
}
@@ -695,6 +733,7 @@ pub struct ProgramExtStatus {
}
impl ProgramExtStatus {
/// Create a new `ProgramExtStatus`.
fn new(name: String, icon: concept::IconRc) -> Self {
Self { name, icon }
}

View File

@@ -38,6 +38,7 @@ pub struct Schema {
}
impl Schema {
/// Create an empty `Schema` with all fields set to their defaults.
pub fn new() -> Self {
Self {
identifier: String::new(),
@@ -76,22 +77,40 @@ impl Schema {
self.path = exe_path.to_string();
}
/// Set the CLSID (Class Identifier) of the application.
///
/// # Todo
///
/// Currently this field is not used by this crate,
/// but you still need to fill it with a legal CLSID for future expanding.
pub fn set_clsid(&mut self, clsid: &str) -> () {
self.clsid = clsid.to_string();
}
/// Set the key referencing a named string resource for the application display name.
///
/// This field is optional and can pass `None` to clear it.
pub fn set_name(&mut self, name: Option<&str>) -> () {
self.name = name.map(|n| n.to_string());
}
/// Set the key referencing a named icon resource for the application default icon.
///
/// This field is optional and can pass `None` to clear it.
pub fn set_icon(&mut self, icon: Option<&str>) -> () {
self.icon = icon.map(|i| i.to_string());
}
/// Set the key referencing a named behavior resource for the application default execution behavior.
///
/// This field is optional and can pass `None` to clear it.
pub fn set_behavior(&mut self, behavior: Option<&str>) -> () {
self.behavior = behavior.map(|b| b.to_string());
}
/// Add a named string resource entry.
///
/// Returns error if the name already exists.
pub fn add_str(&mut self, name: &str, value: &str) -> Result<(), SchemaError> {
match self.strs.insert(name.to_string(), value.to_string()) {
Some(_) => Err(SchemaError::DuplicateKey(name.to_string())),
@@ -99,6 +118,9 @@ impl Schema {
}
}
/// Add a named icon resource entry.
///
/// Returns error if the name already exists.
pub fn add_icon(&mut self, name: &str, value: &str) -> Result<(), SchemaError> {
match self.icons.insert(name.to_string(), value.to_string()) {
Some(_) => Err(SchemaError::DuplicateKey(name.to_string())),
@@ -106,6 +128,9 @@ impl Schema {
}
}
/// Add a named behavior (command line) entry.
///
/// Returns error if the name already exists.
pub fn add_behavior(&mut self, name: &str, value: &str) -> Result<(), SchemaError> {
match self.behaviors.insert(name.to_string(), value.to_string()) {
Some(_) => Err(SchemaError::DuplicateKey(name.to_string())),
@@ -116,6 +141,8 @@ impl Schema {
/// Add a file extension to the schema.
///
/// The parameter `ext` is the file extension without leading dot `.`.
/// And the parameter `ext_name`, `ext_icon` and `ext_behavior` are the key
/// referencing a named string resource, icon resource and behavior resource respectively.
pub fn add_ext(
&mut self,
ext: &str,
@@ -135,42 +162,55 @@ impl Schema {
}
impl Schema {
/// Get the identifier of the schema.
pub(super) fn get_identifier(&self) -> &str {
&self.identifier
}
/// Get the absolute path to the executable file.
pub(super) fn get_path(&self) -> &str {
&self.path
}
/// Get the CLSID (Class Identifier) of the application.
pub(super) fn get_clsid(&self) -> &str {
&self.clsid
}
/// Get the key referencing the named string resource for the display name.
/// Return `None` if user doesn't specify this.
pub(super) fn get_name(&self) -> Option<&str> {
self.name.as_ref().map(|v| v.as_str())
}
/// Get the key referencing the named icon resource for the default icon.
/// Return `None` if user doesn't specify this.
pub(super) fn get_icon(&self) -> Option<&str> {
self.icon.as_ref().map(|v| v.as_str())
}
/// Get the key referencing the named behavior resource for the default verb.
/// Return `None` if user doesn't specify this.
pub(super) fn get_behavior(&self) -> Option<&str> {
self.behavior.as_ref().map(|v| v.as_str())
}
/// Get a reference to the string resources map.
pub(super) fn get_strs(&self) -> &HashMap<String, String> {
&self.strs
}
/// Get a reference to the icon resources map.
pub(super) fn get_icons(&self) -> &HashMap<String, String> {
&self.icons
}
/// Get a reference to the behavior resources map.
pub(super) fn get_behaviors(&self) -> &HashMap<String, String> {
&self.behaviors
}
/// Get a reference to the file extensions map.
pub(super) fn get_exts(&self) -> &HashMap<String, SchemaExt> {
&self.exts
}
@@ -189,6 +229,7 @@ pub(crate) struct SchemaExt {
}
impl SchemaExt {
/// Create a new `SchemaExt` with the given name, icon key and behavior key.
fn new(name: &str, icon: &str, behavior: &str) -> Self {
Self {
name: name.to_string(),
@@ -199,14 +240,17 @@ impl SchemaExt {
}
impl SchemaExt {
/// Get the key referencing the named string resource for display name.
pub(super) fn get_name(&self) -> &str {
&self.name
}
/// Get the key referencing the named icon resource for file icon.
pub(super) fn get_icon(&self) -> &str {
&self.icon
}
/// Get the key referencing the named behavior resource.
pub(super) fn get_behavior(&self) -> &str {
&self.behavior
}

View File

@@ -294,7 +294,7 @@ impl Clsid {
/// The error occurs when parsing CLSID.
#[derive(Debug, TeError)]
#[error("given string \"{inner}\" is invalid for uuid")]
#[error("given string \"{inner}\" is invalid for CLSID")]
pub struct ParseClsidError {
/// The clone of string which is not a valid CLSID.
inner: String,