feat: finish highlevel register function
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use crate::{lowlevel, utilities, win32::concept};
|
use crate::{lowlevel, utilities, win32::{self, concept}};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
@@ -45,7 +45,31 @@ pub enum ParseProgramError {
|
|||||||
|
|
||||||
/// 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}")]
|
||||||
|
Lowlevel(#[from] lowlevel::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region: Utilities
|
||||||
|
|
||||||
|
/// The println macro only works on Debug mode
|
||||||
|
/// for tracing the execution of some important functions.
|
||||||
|
macro_rules! debug_println {
|
||||||
|
// For no argument.
|
||||||
|
() => {
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
eprintln!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// For one or more arguments like println!.
|
||||||
|
($($arg:tt)*) => {
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
eprintln!($($arg)*);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
@@ -54,10 +78,10 @@ pub enum ProgramError {}
|
|||||||
// region: Schema Body
|
// region: Schema Body
|
||||||
|
|
||||||
/// The sketchpad of complete [Program].
|
/// The sketchpad of complete [Program].
|
||||||
///
|
///
|
||||||
/// In suggested usage, we will create a [Schema] first,
|
/// In suggested usage, we will create a [Schema] first,
|
||||||
/// fill some essential and optional properties,
|
/// fill some essential and optional properties,
|
||||||
/// then add file extensions which we need.
|
/// then add file extensions which we need.
|
||||||
/// And finally convert it into immutable [Program] for formal using.
|
/// And finally convert it into immutable [Program] for formal using.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Schema {
|
pub struct Schema {
|
||||||
@@ -92,7 +116,7 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the identifier of the schema.
|
/// Set the identifier of the schema.
|
||||||
///
|
///
|
||||||
/// The identifier is used to build ProgId.
|
/// The identifier is used to build ProgId.
|
||||||
/// So it should starts with an ASCII letter and followed by zero or more ASCII letters, digits, underline and hyphen.
|
/// So it should starts with an ASCII letter and followed by zero or more ASCII letters, digits, underline and hyphen.
|
||||||
/// And it should not be empty.
|
/// And it should not be empty.
|
||||||
@@ -143,7 +167,7 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add a file extension to the schema.
|
/// Add a file extension to the schema.
|
||||||
///
|
///
|
||||||
/// The parameter `ext` is the file extension without leading dot `.`.
|
/// The parameter `ext` is the file extension without leading dot `.`.
|
||||||
pub fn add_ext(
|
pub fn add_ext(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -162,7 +186,7 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Try converting [Schema] into [Program].
|
/// Try converting [Schema] into [Program].
|
||||||
///
|
///
|
||||||
/// This is equivalent to [Program::new].
|
/// This is equivalent to [Program::new].
|
||||||
pub fn into_program(self) -> Result<Program, ParseProgramError> {
|
pub fn into_program(self) -> Result<Program, ParseProgramError> {
|
||||||
Program::new(self)
|
Program::new(self)
|
||||||
@@ -203,8 +227,8 @@ impl SchemaExt {
|
|||||||
pub struct Program {
|
pub struct Program {
|
||||||
app_paths_key: lowlevel::AppPathsKey,
|
app_paths_key: lowlevel::AppPathsKey,
|
||||||
applications_key: lowlevel::ApplicationsKey,
|
applications_key: lowlevel::ApplicationsKey,
|
||||||
file_name: String,
|
app_path: String,
|
||||||
dir_name: String,
|
app_dir_path: String,
|
||||||
name: Option<Rc<ProgramStr>>,
|
name: Option<Rc<ProgramStr>>,
|
||||||
icon: Option<Rc<ProgramIcon>>,
|
icon: Option<Rc<ProgramIcon>>,
|
||||||
behavior: Option<Rc<ProgramBehavior>>,
|
behavior: Option<Rc<ProgramBehavior>>,
|
||||||
@@ -213,8 +237,7 @@ pub struct Program {
|
|||||||
icons: Vec<Rc<ProgramIcon>>,
|
icons: Vec<Rc<ProgramIcon>>,
|
||||||
behaviors: Vec<Rc<ProgramBehavior>>,
|
behaviors: Vec<Rc<ProgramBehavior>>,
|
||||||
|
|
||||||
progid_keys: Vec<Rc<ProgramProgIdKey>>,
|
ext_keys: Vec<ProgramProgIdExtKey>,
|
||||||
ext_keys: Vec<ProgramExtKey>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<Schema> for Program {
|
impl TryFrom<Schema> for Program {
|
||||||
@@ -236,7 +259,7 @@ impl Program {
|
|||||||
|
|
||||||
/// Extract the start in path from full path to application,
|
/// Extract the start in path from full path to application,
|
||||||
/// which basically is the stem of full path.
|
/// which basically is the stem of full path.
|
||||||
fn extract_dir_name(full_path: &Path) -> Result<&OsStr, ParseProgramError> {
|
fn extract_dir_path(full_path: &Path) -> Result<&OsStr, ParseProgramError> {
|
||||||
full_path
|
full_path
|
||||||
.parent()
|
.parent()
|
||||||
.map(|p| p.as_os_str())
|
.map(|p| p.as_os_str())
|
||||||
@@ -299,19 +322,20 @@ impl Program {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Try converting [Schema] into [Program].
|
/// Try converting [Schema] into [Program].
|
||||||
///
|
///
|
||||||
/// During this process, some checks will be performed to ensure the validity of the data.
|
/// During this process, some checks will be performed to ensure the validity of the data.
|
||||||
/// For example, the reference to icon, name, or behavior must exist in their respective dictionaries.
|
/// For example, the reference to icon, name, or behavior must exist in their respective dictionaries.
|
||||||
/// The identifier must be suit for building ProgId.
|
/// The identifier must be suit for building ProgId.
|
||||||
pub fn new(schema: Schema) -> Result<Self, ParseProgramError> {
|
pub fn new(schema: Schema) -> Result<Self, ParseProgramError> {
|
||||||
// Extract file name part and directory name part respectively.
|
// Extract file name part and directory name part respectively.
|
||||||
let schema_path = Path::new(&schema.path);
|
let schema_path = Path::new(&schema.path);
|
||||||
let file_name = Self::extract_file_name(schema_path)?;
|
let app_path = schema.path.clone();
|
||||||
let file_name = String::from(utilities::osstr_to_str(file_name)?);
|
let app_file_name = Self::extract_file_name(schema_path)?;
|
||||||
let dir_name = Self::extract_dir_name(schema_path)?;
|
let app_file_name = String::from(utilities::osstr_to_str(app_file_name)?);
|
||||||
let dir_name = String::from(utilities::osstr_to_str(dir_name)?);
|
let app_dir_path = Self::extract_dir_path(schema_path)?;
|
||||||
|
let app_dir_path = String::from(utilities::osstr_to_str(app_dir_path)?);
|
||||||
// Build app paths key and applications key respectively
|
// Build app paths key and applications key respectively
|
||||||
let key = concept::FileName::new(&file_name)?;
|
let key = concept::FileName::new(&app_file_name)?;
|
||||||
let app_paths_key = lowlevel::AppPathsKey::new(key.clone());
|
let app_paths_key = lowlevel::AppPathsKey::new(key.clone());
|
||||||
let applications_key = lowlevel::ApplicationsKey::new(key.clone());
|
let applications_key = lowlevel::ApplicationsKey::new(key.clone());
|
||||||
|
|
||||||
@@ -355,8 +379,7 @@ impl Program {
|
|||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
// We build ProgIdKey and ExtKey list at the same time
|
// We build ProgIdKey and ExtKey list at the same time
|
||||||
let mut progid_keys: Vec<Rc<ProgramProgIdKey>> = Vec::with_capacity(schema.exts.len());
|
let mut ext_keys: Vec<ProgramProgIdExtKey> = Vec::with_capacity(schema.exts.len());
|
||||||
let mut ext_keys: Vec<ProgramExtKey> = Vec::with_capacity(schema.exts.len());
|
|
||||||
for (key, value) in &schema.exts {
|
for (key, value) in &schema.exts {
|
||||||
// Build ProgId first.
|
// Build ProgId first.
|
||||||
let progid = Self::build_progid(&schema.identifier, key.as_str())?;
|
let progid = Self::build_progid(&schema.identifier, key.as_str())?;
|
||||||
@@ -368,44 +391,35 @@ impl Program {
|
|||||||
let icon = Self::resolve_index(&value.icon, &icons, &icons_index_map)?;
|
let icon = Self::resolve_index(&value.icon, &icons, &icons_index_map)?;
|
||||||
let behavior = Self::resolve_index(&value.behavior, &behaviors, &behaviors_index_map)?;
|
let behavior = Self::resolve_index(&value.behavior, &behaviors, &behaviors_index_map)?;
|
||||||
|
|
||||||
// Create program ProgId key struct
|
|
||||||
let progid_key = ProgramProgIdKey {
|
|
||||||
key: progid_key,
|
|
||||||
name,
|
|
||||||
icon,
|
|
||||||
behavior,
|
|
||||||
};
|
|
||||||
// Create Rc style
|
|
||||||
let progid_key = Rc::new(progid_key);
|
|
||||||
|
|
||||||
// Build Ext.
|
// Build Ext.
|
||||||
let ext = concept::Ext::new(key.as_str())?;
|
let ext = concept::Ext::new(key.as_str())?;
|
||||||
let ext_key = lowlevel::ExtKey::new(ext);
|
let ext_key = lowlevel::ExtKey::new(ext);
|
||||||
|
|
||||||
// Create program Ext key struct
|
// Create program Ext key struct
|
||||||
let ext_key = ProgramExtKey {
|
let progid_ext_key = ProgramProgIdExtKey {
|
||||||
key: ext_key,
|
ext_key,
|
||||||
assoc: progid_key.clone(),
|
progid_key,
|
||||||
|
name,
|
||||||
|
icon,
|
||||||
|
behavior,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add them into list
|
// Add them into list
|
||||||
progid_keys.push(progid_key);
|
ext_keys.push(progid_ext_key);
|
||||||
ext_keys.push(ext_key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything is okey
|
// Everything is okey
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
app_paths_key,
|
app_paths_key,
|
||||||
applications_key,
|
applications_key,
|
||||||
file_name,
|
app_path,
|
||||||
dir_name,
|
app_dir_path,
|
||||||
name,
|
name,
|
||||||
icon,
|
icon,
|
||||||
behavior,
|
behavior,
|
||||||
strs,
|
strs,
|
||||||
icons,
|
icons,
|
||||||
behaviors,
|
behaviors,
|
||||||
progid_keys,
|
|
||||||
ext_keys,
|
ext_keys,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -414,16 +428,62 @@ impl Program {
|
|||||||
impl Program {
|
impl Program {
|
||||||
/// Register this application.
|
/// Register this application.
|
||||||
///
|
///
|
||||||
/// If there is registration of this application,
|
/// If there is complete or partial registration of this application
|
||||||
/// this function will return error.
|
/// (partial registration may occurs when registration failed),
|
||||||
|
/// this function does nothing.
|
||||||
pub fn register(&mut self, scope: Scope) -> Result<(), ProgramError> {
|
pub fn register(&mut self, scope: Scope) -> Result<(), ProgramError> {
|
||||||
todo!()
|
// Create App Paths subkey
|
||||||
|
debug_println!("Adding App Paths subkey...");
|
||||||
|
self.app_paths_key.ensure(scope)?;
|
||||||
|
// Write App Paths values
|
||||||
|
self.app_paths_key.set_default(scope, &self.app_path)?;
|
||||||
|
self.app_paths_key.set_path(scope, &self.app_dir_path)?;
|
||||||
|
|
||||||
|
// Create Applications subkey
|
||||||
|
debug_println!("Adding Applications subkey...");
|
||||||
|
self.applications_key.ensure(scope)?;
|
||||||
|
// Write Applications values
|
||||||
|
self.applications_key
|
||||||
|
.set_shell_verb(scope, self.behavior.as_ref().map(|beh| &beh.inner))?;
|
||||||
|
self.applications_key
|
||||||
|
.set_default_icon(scope, self.icon.as_ref().map(|ico| &ico.inner))?;
|
||||||
|
self.applications_key
|
||||||
|
.set_friendly_app_name(scope, self.name.as_ref().map(|name| &name.inner))?;
|
||||||
|
let exts: Vec<&concept::Ext> = self
|
||||||
|
.ext_keys
|
||||||
|
.iter()
|
||||||
|
.map(|key| key.ext_key.inner())
|
||||||
|
.collect();
|
||||||
|
self.applications_key
|
||||||
|
.set_supported_types(scope, Some(&exts))?;
|
||||||
|
self.applications_key.set_no_open_with(scope, true)?;
|
||||||
|
|
||||||
|
// Create ProgId subkeys one by one
|
||||||
|
debug_println!("Adding ProgId subkey...");
|
||||||
|
for program_progid_key in &mut self.ext_keys {
|
||||||
|
let progid_key = &mut program_progid_key.progid_key;
|
||||||
|
|
||||||
|
// Create ProgId subkey
|
||||||
|
debug_println!("Adding ProgId \"{0}\" subkey...", progid_key.inner().to_string());
|
||||||
|
progid_key.ensure(scope)?;
|
||||||
|
// Write ProgId values
|
||||||
|
let name = Some(&program_progid_key.name.inner);
|
||||||
|
progid_key.set_default(scope, name)?;
|
||||||
|
progid_key.set_shell_verb(scope, &program_progid_key.behavior.inner)?;
|
||||||
|
progid_key.set_friendly_type_name(scope, name)?;
|
||||||
|
progid_key.set_default_icon(scope, Some(&program_progid_key.icon.inner))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything is okey.
|
||||||
|
// Notify changes and return
|
||||||
|
win32::utilities::notify_assoc_changed();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unregister this application.
|
/// Unregister this application.
|
||||||
///
|
///
|
||||||
/// If there is no registration of this application,
|
/// No matter whether there is registration of this application,
|
||||||
/// this function will return error.
|
/// this function always make sure that there is no registration after running this function.
|
||||||
pub fn unregister(&mut self, scope: Scope) -> Result<(), ProgramError> {
|
pub fn unregister(&mut self, scope: Scope) -> Result<(), ProgramError> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
@@ -472,22 +532,20 @@ struct ProgramBehavior {
|
|||||||
inner: lowlevel::ShellVerb,
|
inner: lowlevel::ShellVerb,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal used struct presenting a Program ProgId.
|
/// Internal used struct presenting a Program ProgId and associated file extension.
|
||||||
|
///
|
||||||
|
/// Another reason combine ProgId and Ext is that we can't operate ProgId in mutable mode,
|
||||||
|
/// due to the internal immutable of Rc in Rust.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ProgramProgIdKey {
|
struct ProgramProgIdExtKey {
|
||||||
key: lowlevel::ProgIdKey,
|
ext_key: lowlevel::ExtKey,
|
||||||
|
|
||||||
|
progid_key: lowlevel::ProgIdKey,
|
||||||
name: Rc<ProgramStr>,
|
name: Rc<ProgramStr>,
|
||||||
icon: Rc<ProgramIcon>,
|
icon: Rc<ProgramIcon>,
|
||||||
behavior: Rc<ProgramBehavior>,
|
behavior: Rc<ProgramBehavior>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal used struct presenting a Program file extension.
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct ProgramExtKey {
|
|
||||||
key: lowlevel::ExtKey,
|
|
||||||
assoc: Rc<ProgramProgIdKey>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|||||||
@@ -603,11 +603,11 @@ impl ApplicationsKey {
|
|||||||
const NAMEOF_SHELL_VERB_PART1: &str = "shell";
|
const NAMEOF_SHELL_VERB_PART1: &str = "shell";
|
||||||
const NAMEOF_SHELL_VERB_PART3: &str = "command";
|
const NAMEOF_SHELL_VERB_PART3: &str = "command";
|
||||||
|
|
||||||
pub fn get_shell_verb(&self, view: View) -> Result<ShellVerb, Error> {
|
pub fn get_shell_verb(&self, view: View) -> Result<Option<ShellVerb>, Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_shell_verb(&mut self, scope: Scope, sv: &ShellVerb) -> Result<(), Error> {
|
pub fn set_shell_verb(&mut self, scope: Scope, sv: Option<&ShellVerb>) -> Result<(), Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -618,7 +618,7 @@ impl ApplicationsKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_default_icon(
|
pub fn set_default_icon(
|
||||||
&self,
|
&mut self,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
icon: Option<&IconResVariant>,
|
icon: Option<&IconResVariant>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
@@ -632,7 +632,7 @@ impl ApplicationsKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_friendly_app_name(
|
pub fn set_friendly_app_name(
|
||||||
&self,
|
&mut self,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
name: Option<&StrResVariant>,
|
name: Option<&StrResVariant>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
@@ -646,10 +646,11 @@ impl ApplicationsKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_supported_types(
|
pub fn set_supported_types(
|
||||||
&self,
|
&mut self,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
tys: Option<&[concept::Ext]>,
|
tys: Option<&[&concept::Ext]>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
// TODO: If given slice is empty, do not create this key.
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,7 +660,7 @@ impl ApplicationsKey {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_no_open_with(&self, scope: Scope, flag: bool) -> Result<(), Error> {
|
pub fn set_no_open_with(&mut self, scope: Scope, flag: bool) -> Result<(), Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -722,6 +723,18 @@ impl ExtKey {
|
|||||||
Ok(OpenedKey::new(classes, this_ext))
|
Ok(OpenedKey::new(classes, this_ext))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_exist(&self, view: View) -> Result<bool, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ensure(&mut self, scope: Scope) -> Result<bool, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(&mut self, scope: Scope) -> Result<(), Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
// YYC MARK:
|
// YYC MARK:
|
||||||
// We do not support "Content Type" and "PerceivedType"
|
// We do not support "Content Type" and "PerceivedType"
|
||||||
// because current interface are enough to use,
|
// because current interface are enough to use,
|
||||||
@@ -795,6 +808,18 @@ impl ProgIdKey {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_exist(&self, view: View) -> Result<bool, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ensure(&mut self, scope: Scope) -> Result<bool, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(&mut self, scope: Scope) -> Result<(), Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
// YYC MARK:
|
// YYC MARK:
|
||||||
// Currently we only support (Default), FriendlyTypeName and DefaultIcon
|
// Currently we only support (Default), FriendlyTypeName and DefaultIcon
|
||||||
// to just cover the basic usage.
|
// to just cover the basic usage.
|
||||||
@@ -805,6 +830,9 @@ impl ProgIdKey {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// The legacy way to set friendly name for this ProgId.
|
||||||
pub fn set_default(&mut self, scope: Scope, name: Option<&StrResVariant>) -> Result<(), Error> {
|
pub fn set_default(&mut self, scope: Scope, name: Option<&StrResVariant>) -> Result<(), Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
@@ -826,8 +854,11 @@ impl ProgIdKey {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// Set this entry to a friendly name for the ProgID.
|
||||||
pub fn set_friendly_type_name(
|
pub fn set_friendly_type_name(
|
||||||
&self,
|
&mut self,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
name: Option<&StrResVariant>,
|
name: Option<&StrResVariant>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
@@ -841,7 +872,7 @@ impl ProgIdKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_default_icon(
|
pub fn set_default_icon(
|
||||||
&self,
|
&mut self,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
icon: Option<&IconResVariant>,
|
icon: Option<&IconResVariant>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|||||||
@@ -5,24 +5,6 @@ use std::iter::FusedIterator;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use thiserror::Error as TeError;
|
use thiserror::Error as TeError;
|
||||||
|
|
||||||
/// The println macro only works on Debug mode
|
|
||||||
/// for tracing the execution of some important functions.
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! debug_println {
|
|
||||||
// For no argument.
|
|
||||||
() => {
|
|
||||||
if cfg!(debug_assertions) {
|
|
||||||
eprintln!();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// For one or more arguments like println!.
|
|
||||||
($($arg:tt)*) => {
|
|
||||||
if cfg!(debug_assertions) {
|
|
||||||
eprintln!($($arg)*);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// region: OS String Related
|
// region: OS String Related
|
||||||
|
|
||||||
/// The error occurs when casting `OsStr` into `str`.
|
/// The error occurs when casting `OsStr` into `str`.
|
||||||
|
|||||||
Reference in New Issue
Block a user