feat: write some highlevel code
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
use crate::lowlevel;
|
||||
use crate::{lowlevel, utilities, win32};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsStr;
|
||||
use std::rc::Rc;
|
||||
use std::path::Path;
|
||||
use thiserror::Error as TeError;
|
||||
|
||||
pub use lowlevel::{Scope, View};
|
||||
@@ -15,7 +18,16 @@ pub enum SchemaError {
|
||||
|
||||
/// Error occurs when trying converting `Schema` into `Program`.
|
||||
#[derive(Debug, TeError)]
|
||||
pub enum ParseProgramError {}
|
||||
pub enum ParseProgramError {
|
||||
#[error("{0}")]
|
||||
BadFileName(#[from] win32::concept::BadFileNameError),
|
||||
#[error("{0}")]
|
||||
CastOsStr(#[from] utilities::CastOsStrError),
|
||||
#[error("given path doesn't has legal file name part")]
|
||||
NoFileNamePart,
|
||||
#[error("given path doesn't has legal directory part")]
|
||||
NoDirNamePart,
|
||||
}
|
||||
|
||||
/// Error occurs when operating with `Program`.
|
||||
#[derive(Debug, TeError)]
|
||||
@@ -161,7 +173,20 @@ impl SchemaExt {
|
||||
|
||||
/// Program is a complete and immutable program representer
|
||||
pub struct Program {
|
||||
app_paths_key: lowlevel::AppPathsKey,
|
||||
applications_key: lowlevel::ApplicationsKey,
|
||||
file_name: String,
|
||||
dir_name: String,
|
||||
name: Rc<ProgramStr>,
|
||||
icon: Rc<ProgramIcon>,
|
||||
behavior: Rc<ProgramBehavior>,
|
||||
|
||||
strs: Vec<Rc<ProgramStr>>,
|
||||
icons: Vec<Rc<ProgramIcon>>,
|
||||
behaviors: Vec<Rc<ProgramBehavior>>,
|
||||
|
||||
progid_keys: Vec<Rc<ProgramProgIdKey>>,
|
||||
ext_keys: Vec<ProgramExtKey>,
|
||||
}
|
||||
|
||||
impl TryFrom<Schema> for Program {
|
||||
@@ -173,9 +198,43 @@ impl TryFrom<Schema> for Program {
|
||||
}
|
||||
|
||||
impl Program {
|
||||
/// Extract the file name part from full path to application,
|
||||
/// which was used in Registry path component.
|
||||
fn extract_file_name(full_path: &Path) -> Result<&OsStr, ParseProgramError> {
|
||||
full_path
|
||||
.file_name()
|
||||
.ok_or(ParseProgramError::NoFileNamePart)
|
||||
}
|
||||
|
||||
/// Extract the start in path from full path to application,
|
||||
/// which basically is the stem of full path.
|
||||
fn extract_dir_name(full_path: &Path) -> Result<&OsStr, ParseProgramError> {
|
||||
full_path
|
||||
.parent()
|
||||
.map(|p| p.as_os_str())
|
||||
.ok_or(ParseProgramError::NoDirNamePart)
|
||||
}
|
||||
|
||||
/// Try creating Program from Schema.
|
||||
pub fn new(schema: Schema) -> Result<Self, ParseProgramError> {
|
||||
todo!()
|
||||
// Extract file name part and directory name part respectively.
|
||||
let schema_path = Path::new(&schema.path);
|
||||
let file_name = Self::extract_file_name(schema_path)?;
|
||||
let file_name = String::from(utilities::osstr_to_str(file_name)?);
|
||||
let dir_name = Self::extract_dir_name(schema_path)?;
|
||||
let dir_name = String::from(utilities::osstr_to_str(dir_name)?);
|
||||
// Build app paths key and applications key respectively
|
||||
let key = win32::concept::FileName::new(&file_name)?;
|
||||
let app_paths_key = lowlevel::AppPathsKey::new(key.clone());
|
||||
let applications_key = lowlevel::ApplicationsKey::new(key.clone());
|
||||
|
||||
todo!();
|
||||
// Ok(Self {
|
||||
// app_paths_key,
|
||||
// applications_key,
|
||||
// file_name,
|
||||
// dir_name,
|
||||
// })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +258,8 @@ 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`.
|
||||
pub fn is_registered(&self, view: View) -> Result<bool, ProgramError> {
|
||||
todo!()
|
||||
}
|
||||
@@ -208,6 +269,41 @@ impl Program {
|
||||
|
||||
// region: Program Internals
|
||||
|
||||
/// Internal used enum presenting a Program string resource.
|
||||
#[derive(Debug)]
|
||||
enum ProgramStr {
|
||||
Plain(String),
|
||||
RefStr(win32::concept::StrRefStr)
|
||||
}
|
||||
|
||||
/// Internal used enum presenting a Program icon resource.
|
||||
#[derive(Debug)]
|
||||
enum ProgramIcon {
|
||||
Plain(String),
|
||||
RefStr(win32::concept::IconRefStr)
|
||||
}
|
||||
|
||||
/// Internal used enum presenting a Program behavior (command line setups).
|
||||
#[derive(Debug)]
|
||||
struct ProgramBehavior {
|
||||
inner: String,
|
||||
}
|
||||
|
||||
/// Internal used struct presenting a Program ProgId.
|
||||
#[derive(Debug)]
|
||||
struct ProgramProgIdKey {
|
||||
key: lowlevel::ProgIdKey,
|
||||
name: Rc<ProgramStr>,
|
||||
icon: Rc<ProgramIcon>,
|
||||
behavior: Rc<ProgramBehavior>,
|
||||
}
|
||||
|
||||
/// Internal used struct presenting a Program file extension.
|
||||
#[derive(Debug)]
|
||||
struct ProgramExtKey {
|
||||
key: lowlevel::ExtKey,
|
||||
assoc: Rc<ProgramProgIdKey>
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
|
||||
@@ -88,16 +88,44 @@ impl Scope {
|
||||
|
||||
// endregion
|
||||
|
||||
// region: App Paths Key
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct AppPathsKey {
|
||||
key: win32::concept::FileName,
|
||||
}
|
||||
|
||||
impl AppPathsKey {
|
||||
pub fn new(inner: win32::concept::FileName) -> Self {
|
||||
Self { key: inner }
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> &win32::concept::FileName {
|
||||
&self.key
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region: Applications Key
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct ApplicationsKey {
|
||||
key: win32::concept::FileName,
|
||||
}
|
||||
|
||||
impl ApplicationsKey {
|
||||
pub fn new(inner: win32::concept::FileName) -> Self {
|
||||
Self { key: inner }
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> &win32::concept::FileName {
|
||||
&self.key
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region: File Extension Key
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
@@ -156,6 +184,16 @@ impl ExtKey {
|
||||
|
||||
}
|
||||
|
||||
impl ExtKey {
|
||||
pub fn new(inner: win32::concept::Ext) -> Self {
|
||||
Self { ext: inner }
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> &win32::concept::Ext {
|
||||
&self.ext
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region: ProgId Key
|
||||
@@ -164,11 +202,11 @@ impl ExtKey {
|
||||
|
||||
/// The enum representing a losse Programmatic Identifiers (ProgId).
|
||||
///
|
||||
/// In real world, not all software developers are willing to following Microsoft suggestions to use ProgId,
|
||||
/// In real world, not all software developers are willing to following Microsoft suggestions to use ProgId.
|
||||
/// They use string which do not have any regulation as ProgId.
|
||||
/// This enum is designed for handling this scenario.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
enum LosseProgId {
|
||||
pub enum LosseProgId {
|
||||
Plain(String),
|
||||
Strict(win32::concept::ProgId),
|
||||
}
|
||||
@@ -203,6 +241,16 @@ pub struct ProgIdKey {
|
||||
progid: LosseProgId,
|
||||
}
|
||||
|
||||
impl ProgIdKey {
|
||||
pub fn new(inner: LosseProgId) -> Self {
|
||||
Self { progid: inner }
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> &LosseProgId {
|
||||
&self.progid
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// endregion
|
||||
|
||||
@@ -321,6 +321,7 @@ impl ParseIconRefStrError {
|
||||
///
|
||||
/// As far as I know, the minus token `-` does nothing in this string.
|
||||
/// The following number is just the index.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct IconRefStr {
|
||||
/// The path part of this reference string.
|
||||
/// And it can be expandable.
|
||||
@@ -414,6 +415,7 @@ impl ParseStrRefStrError {
|
||||
///
|
||||
/// As far as I know, the minus token `-` does nothing in this string.
|
||||
/// The following number is just the index.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct StrRefStr {
|
||||
/// The path part of this reference string.
|
||||
/// And it can be expandable.
|
||||
@@ -503,6 +505,7 @@ pub enum IconSizeKind {
|
||||
}
|
||||
|
||||
/// The struct representing a loaded icon resource.
|
||||
#[derive(Debug)]
|
||||
pub struct IconRc {
|
||||
icon: HICON,
|
||||
}
|
||||
@@ -593,6 +596,7 @@ pub enum LoadStrRcError {
|
||||
}
|
||||
|
||||
/// The struct representing a loaded string resource.
|
||||
#[derive(Debug)]
|
||||
pub struct StrRc {
|
||||
inner: String,
|
||||
}
|
||||
@@ -686,6 +690,7 @@ pub enum ExpandEnvVarError {
|
||||
/// The struct representing an Expand String,
|
||||
/// which contain environment variable in string,
|
||||
/// like `%LOCALAPPDATA%\SomeApp.exe`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct ExpandString {
|
||||
inner: String,
|
||||
}
|
||||
@@ -800,6 +805,8 @@ pub enum ParseFileNameError {
|
||||
EmbeddedNul(#[from] widestring::error::ContainsNul<WideChar>),
|
||||
/// Given string has illegal char as Windows file name.
|
||||
InvalidChar,
|
||||
/// Given string is empty.
|
||||
EmptyStr,
|
||||
}
|
||||
|
||||
impl Display for FileName {
|
||||
@@ -814,7 +821,12 @@ impl FromStr for FileName {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
use windows_sys::Win32::UI::Shell::PathCleanupSpec;
|
||||
|
||||
// Make buffer and call function.
|
||||
// If given string is empty, it must be illegal.
|
||||
if s.is_empty() {
|
||||
return Err(ParseFileNameError::EmptyStr);
|
||||
}
|
||||
|
||||
// Make buffer and call Win32 function for checking.
|
||||
let mut spec = WideCString::from_str(s)?;
|
||||
let rv = unsafe { PathCleanupSpec(std::ptr::null(), spec.as_mut_ptr()) };
|
||||
if rv != 0 {
|
||||
|
||||
@@ -35,6 +35,7 @@ fn test_ext_parse() {
|
||||
}
|
||||
|
||||
ok_tester(".jpg", "jpg");
|
||||
err_tester(".");
|
||||
err_tester(".jar.disabled");
|
||||
err_tester("jar");
|
||||
}
|
||||
@@ -247,6 +248,7 @@ fn test_file_name() {
|
||||
}
|
||||
|
||||
ok_tester("GoodExecutable.exe");
|
||||
err_tester("");
|
||||
err_tester("*.?xaml");
|
||||
err_tester(r#"\\\lol///"#);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user