use serde::Deserialize; use std::collections::HashMap; use std::path::Path; use thiserror::Error as TeError; use toml; use wfassoc; // region: Manifest /// Raw user input manifest. /// /// This manifest is the raw input of user. /// Some fields may not be checked due to user invalid input. #[derive(Debug, Deserialize)] pub struct Manifest { identifier: String, path: String, clsid: String, name: Option, icon: Option, behavior: Option, strs: HashMap, icons: HashMap, behaviors: HashMap, exts: HashMap, } /// The sub-type in raw user input manifest. #[derive(Debug, Deserialize)] pub struct ManifestExt { name: String, icon: String, behavior: String, } // endregion // region: Manifest Operation /// Error occurs when parsing manifest TOML file. #[derive(Debug, TeError)] pub enum ParseManifestError { /// Io error #[error("IO error when reading manifest file")] Io(#[from] std::io::Error), /// Toml deserialization error #[error("given TOML manifest file has bad format")] Toml(#[from] toml::de::Error), } impl Manifest { /// Read user manifest. pub fn from_file(path: &Path) -> Result { let contents = std::fs::read_to_string(path)?; let config: Manifest = toml::from_str(&contents)?; Ok(config) } } /// Error occurs when parsing manifest into schema. #[derive(Debug, TeError)] pub enum ParseSchemaError { /// Error when operating with schema. #[error("{0}")] Schema(#[from] wfassoc::highlevel::SchemaError) } impl TryFrom for wfassoc::Schema { type Error = ParseSchemaError; fn try_from(value: Manifest) -> Result { let mut schema = wfassoc::Schema::new(); schema.set_identifier(&value.identifier); schema.set_path(&value.path); schema.set_clsid(&value.clsid); schema.set_name(value.name.as_ref().map(|x| x.as_str())); schema.set_icon(value.icon.as_ref().map(|x| x.as_str())); schema.set_behavior(value.behavior.as_ref().map(|x| x.as_str())); for (key, value) in value.strs { schema.add_str(&key, &value)?; } for (key, value) in value.icons { schema.add_icon(&key, &value)?; } for (key, value) in value.behaviors { schema.add_behavior(&key, &value)?; } for (key, value) in value.exts { schema.add_ext(&key, &value.name, &value.icon, &value.behavior)?; } Ok(schema) } } // endregion