diff --git a/Cargo.lock b/Cargo.lock index 2389b90..887b604 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -213,6 +213,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "toml" version = "1.0.6+spec-1.1.0" @@ -264,6 +284,7 @@ version = "0.1.0" dependencies = [ "notify", "serde", + "thiserror", "toml", ] diff --git a/Cargo.toml b/Cargo.toml index a430fc6..46ae1d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2024" [dependencies] notify = "8.2.0" serde = { version = "1.0.228", features = ["derive"] } +thiserror = "2.0.18" toml = "1.0.6" diff --git a/src/main.rs b/src/main.rs index 0ca9764..b003588 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,34 +1,94 @@ use std::{ - env, - path::{Path, PathBuf}, + env, fs, + path::{self, Path, PathBuf}, sync::mpsc, }; -use notify::{Event, RecursiveMode, Result, Watcher}; -use serde::Deserialize; +use notify::{Event, EventKind, RecursiveMode, Watcher, event::CreateKind}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Serialize)] struct Config { - libraries: LibConfig, + libraries: Option, } -impl Config {} +impl Config { + fn load_or_create() -> Result { + let config_path = + PathBuf::from(env::var("HOME").unwrap()).join(".config/uniloader/config.toml"); -#[derive(Debug, Deserialize)] + if config_path.exists() { + let contents = fs::read_to_string(&config_path).map_err(|_| ConfigError::ConfigErr)?; + let config: Config = toml::from_str(&contents).map_err(|_| ConfigError::ConfigErr)?; + Ok(config) + } else { + fs::create_dir_all(config_path.parent().unwrap()) + .map_err(|_| ConfigError::ConfigErr)?; + let config = Config { libraries: None }; + let contents = toml::to_string_pretty(&config).map_err(|_| ConfigError::ConfigErr)?; + fs::write(&config_path, contents).map_err(|_| ConfigError::ConfigErr)?; + Ok(config) + } + } +} + +#[derive(Debug, Deserialize, Serialize, Clone)] struct LibConfig { - component_search_engine_symbols: PathBuf, - component_serach_engine_footprints: PathBuf, + symacsys_symbols: Option, + symacsys_footprints: Option, } -fn main() -> Result<()> { - let (tx, rx) = mpsc::channel::>(); +enum SourceType { + SymacSys, + UltraLibrarian, +} + +#[derive(Error, Debug)] +enum ConfigError { + #[error("Config error")] + ConfigErr, +} + +#[derive(Error, Debug)] +enum SourceError { + #[error("Unknown Source")] + SourceUnknown, + #[error("Filename Error")] + FilenameError, +} + +fn main() -> notify::Result<()> { + let config = Config::load_or_create().unwrap(); + if config.libraries.is_some() { + if config.libraries.clone().unwrap().symacsys_symbols.is_some() { + println!("{:?}", config.libraries.unwrap().symacsys_symbols.unwrap()); + } + } + let (tx, rx) = mpsc::channel::>(); let mut watcher = notify::recommended_watcher(tx)?; let downloads = PathBuf::from(env::var("HOME").unwrap()).join("Downloads"); - watcher.watch(&downloads, RecursiveMode::Recursive)?; + watcher.watch(&downloads, RecursiveMode::NonRecursive)?; for res in rx { match res { - Ok(event) => println!("event: {:?}", event.paths[0]), + Ok(event) => { + if event.kind != EventKind::Create(CreateKind::File) { + continue; + } + if !validate_zip(&event.paths[0]) { + continue; + } + + let Ok(source_type) = find_source_type(&event.paths[0]) else { + continue; + }; + + match source_type { + SourceType::SymacSys => println!("SymacSys detected"), + SourceType::UltraLibrarian => println!("UltraLibrarian detected"), + } + } Err(e) => println!("watch error: {:?}", e), } } @@ -36,9 +96,27 @@ fn main() -> Result<()> { Ok(()) } -fn validate_lib(path: PathBuf) -> bool { - if path.is_file() { - let filename = path.file_name(); - } - return false; +fn validate_zip(path: &Path) -> bool { + path.is_file() + && path + .extension() + .and_then(|e| e.to_str()) + .map(|e| e.eq_ignore_ascii_case("zip")) + .unwrap_or(false) +} + +fn find_source_type(path: &Path) -> Result { + let name = path + .file_name() + .ok_or(SourceError::FilenameError)? + .to_str() + .ok_or(SourceError::FilenameError)?; + + if name.starts_with("LIB_") { + Ok(SourceType::SymacSys) + } else if name.starts_with("ul_") { + Ok(SourceType::UltraLibrarian) + } else { + Err(SourceError::SourceUnknown) + } }