1
0

feat: finish highlevel convertion

This commit is contained in:
2026-05-07 20:56:23 +08:00
parent fe81541eeb
commit 2da84f8797

View File

@@ -1,8 +1,10 @@
use crate::{lowlevel, utilities, win32::concept};
use regex::Regex;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::path::Path;
use std::rc::Rc;
use std::sync::LazyLock;
use thiserror::Error as TeError;
pub use lowlevel::{Scope, View};
@@ -19,6 +21,10 @@ pub enum SchemaError {
/// Error occurs when trying converting `Schema` into `Program`.
#[derive(Debug, TeError)]
pub enum ParseProgramError {
#[error("{0}")]
BadExtBody(#[from] concept::BadExtBodyError),
#[error("{0}")]
BadProgIdPart(#[from] concept::BadProgIdPartError),
#[error("{0}")]
BadFileName(#[from] concept::BadFileNameError),
#[error("{0}")]
@@ -31,6 +37,10 @@ pub enum ParseProgramError {
NoDirNamePart,
#[error("given identifier is not presented in dict")]
NoSuchIdentifier,
#[error("extension name should not be empty")]
EmptyExtension,
#[error("given program identifier is not allowed")]
BadIdentifier,
}
/// 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(
&mut self,
ext: &str,
@@ -241,14 +254,39 @@ impl Program {
index_map: &HashMap<String, usize>,
) -> Result<Rc<T>, ParseProgramError> {
match index_map.get(key) {
Some(index) => match vector.get(*index) {
Some(value) => Ok(value.clone()),
None => Err(ParseProgramError::NoSuchIdentifier),
},
Some(index) => Ok(vector
.get(*index)
.expect("unexpected invalid index")
.clone()),
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.
pub fn new(schema: Schema) -> Result<Self, ParseProgramError> {
// 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))
.transpose()?;
// Process file extensions.
// We need create ProgIds list and Exts 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<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!();
// Ok(Self {
// app_paths_key,
// applications_key,
// file_name,
// dir_name,
// })
// Build essential fields for program ProgId key struct.
let name = Self::resolve_index(&value.name, &strs, &strs_index_map)?;
let icon = Self::resolve_index(&value.icon, &icons, &icons_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.
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,
})
}
}