feat: finish highlevel convertion
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
use crate::{lowlevel, utilities, win32::concept};
|
use crate::{lowlevel, utilities, win32::concept};
|
||||||
|
use regex::Regex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::sync::LazyLock;
|
||||||
use thiserror::Error as TeError;
|
use thiserror::Error as TeError;
|
||||||
|
|
||||||
pub use lowlevel::{Scope, View};
|
pub use lowlevel::{Scope, View};
|
||||||
@@ -19,6 +21,10 @@ pub enum SchemaError {
|
|||||||
/// 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}")]
|
||||||
|
BadExtBody(#[from] concept::BadExtBodyError),
|
||||||
|
#[error("{0}")]
|
||||||
|
BadProgIdPart(#[from] concept::BadProgIdPartError),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
BadFileName(#[from] concept::BadFileNameError),
|
BadFileName(#[from] concept::BadFileNameError),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
@@ -31,6 +37,10 @@ pub enum ParseProgramError {
|
|||||||
NoDirNamePart,
|
NoDirNamePart,
|
||||||
#[error("given identifier is not presented in dict")]
|
#[error("given identifier is not presented in dict")]
|
||||||
NoSuchIdentifier,
|
NoSuchIdentifier,
|
||||||
|
#[error("extension name should not be empty")]
|
||||||
|
EmptyExtension,
|
||||||
|
#[error("given program identifier is not allowed")]
|
||||||
|
BadIdentifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error occurs when operating with `Program`.
|
/// Error occurs when operating with `Program`.
|
||||||
@@ -124,6 +134,9 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// The passed `ext` string should be without leading dot `.`.
|
||||||
pub fn add_ext(
|
pub fn add_ext(
|
||||||
&mut self,
|
&mut self,
|
||||||
ext: &str,
|
ext: &str,
|
||||||
@@ -241,14 +254,39 @@ impl Program {
|
|||||||
index_map: &HashMap<String, usize>,
|
index_map: &HashMap<String, usize>,
|
||||||
) -> Result<Rc<T>, ParseProgramError> {
|
) -> Result<Rc<T>, ParseProgramError> {
|
||||||
match index_map.get(key) {
|
match index_map.get(key) {
|
||||||
Some(index) => match vector.get(*index) {
|
Some(index) => Ok(vector
|
||||||
Some(value) => Ok(value.clone()),
|
.get(*index)
|
||||||
None => Err(ParseProgramError::NoSuchIdentifier),
|
.expect("unexpected invalid index")
|
||||||
},
|
.clone()),
|
||||||
None => Err(ParseProgramError::NoSuchIdentifier),
|
None => Err(ParseProgramError::NoSuchIdentifier),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Build ProgId from identifier and given file extension.
|
||||||
|
fn build_progid(
|
||||||
|
identifier: &str,
|
||||||
|
ext: &str,
|
||||||
|
) -> Result<lowlevel::LosseProgId, ParseProgramError> {
|
||||||
|
// Use Regex to check identifier
|
||||||
|
static RE: LazyLock<Regex> = LazyLock::new(|| {
|
||||||
|
Regex::new(r"^[a-zA-Z][a-zA-Z0-9_-]*$").expect("unexpected bad regex pattern string")
|
||||||
|
});
|
||||||
|
let identifier = match RE.captures(identifier) {
|
||||||
|
Some(_) => identifier,
|
||||||
|
None => return Err(ParseProgramError::BadIdentifier),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Capitalize first ASCII of ext
|
||||||
|
let ext = utilities::capitalize_first_ascii(ext);
|
||||||
|
|
||||||
|
// Build strict ProgId
|
||||||
|
let progid = concept::ProgId::new(identifier, &ext, None)?;
|
||||||
|
// Then build losse ProgId
|
||||||
|
let losse_progid: lowlevel::LosseProgId = progid.into();
|
||||||
|
// Return built result
|
||||||
|
Ok(losse_progid)
|
||||||
|
}
|
||||||
|
|
||||||
/// Try creating Program from Schema.
|
/// Try creating Program from Schema.
|
||||||
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.
|
||||||
@@ -301,16 +339,60 @@ impl Program {
|
|||||||
.map(|behavior| Self::resolve_index(&behavior, &behaviors, &behaviors_index_map))
|
.map(|behavior| Self::resolve_index(&behavior, &behaviors, &behaviors_index_map))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
// Process file extensions.
|
// We build ProgIdKey and ExtKey list at the same time
|
||||||
// We need create ProgIds list and Exts list at the same time.
|
let mut progid_keys: Vec<Rc<ProgramProgIdKey>> = Vec::with_capacity(schema.exts.len());
|
||||||
|
let mut ext_keys: Vec<ProgramExtKey> = Vec::with_capacity(schema.exts.len());
|
||||||
|
for (key, value) in &schema.exts {
|
||||||
|
// Build ProgId first.
|
||||||
|
let progid = Self::build_progid(&schema.identifier, key.as_str())?;
|
||||||
|
// Then build ProgId key.
|
||||||
|
let progid_key = lowlevel::ProgIdKey::new(progid);
|
||||||
|
|
||||||
todo!();
|
// Build essential fields for program ProgId key struct.
|
||||||
// Ok(Self {
|
let name = Self::resolve_index(&value.name, &strs, &strs_index_map)?;
|
||||||
// app_paths_key,
|
let icon = Self::resolve_index(&value.icon, &icons, &icons_index_map)?;
|
||||||
// applications_key,
|
let behavior = Self::resolve_index(&value.behavior, &behaviors, &behaviors_index_map)?;
|
||||||
// file_name,
|
|
||||||
// dir_name,
|
// 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.
|
||||||
|
let ext = concept::Ext::new(key.as_str())?;
|
||||||
|
let ext_key = lowlevel::ExtKey::new(ext);
|
||||||
|
|
||||||
|
// Create program Ext key struct
|
||||||
|
let ext_key = ProgramExtKey {
|
||||||
|
key: ext_key,
|
||||||
|
assoc: progid_key.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add them into list
|
||||||
|
progid_keys.push(progid_key);
|
||||||
|
ext_keys.push(ext_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything is okey
|
||||||
|
Ok(Self {
|
||||||
|
app_paths_key,
|
||||||
|
applications_key,
|
||||||
|
file_name,
|
||||||
|
dir_name,
|
||||||
|
name,
|
||||||
|
icon,
|
||||||
|
behavior,
|
||||||
|
strs,
|
||||||
|
icons,
|
||||||
|
behaviors,
|
||||||
|
progid_keys,
|
||||||
|
ext_keys,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user