use crate::models::context::ContextModel;
use crate::system::arch::SystemArchProvider;
use crate::system::date::SystemDateProvider;
use crate::system::dir_download::SystemDirDownloadProvider;
use crate::system::dir_home::SystemDirHomeProvider;
use crate::system::dir_pwd::SystemDirPwdProvider;
use crate::system::dir_temp::SystemDirTempProvider;
use crate::system::hostname::SystemHostnameProvider;
use crate::system::language::SystemLanguageProvider;
use crate::system::os::SystemOsProvider;
use crate::system::pid::SystemPidProvider;
use crate::system::shell::SystemShellProvider;
use crate::system::time::SystemTimeProvider;
use crate::system::user::SystemUserProvider;
use anyhow::Result;
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SystemKey {
Arch,
Date,
DirDownload,
DirHome,
DirPwd,
DirTemp,
Hostname,
Language,
Os,
Pid,
Shell,
Time,
User,
}
impl SystemKey {
pub fn as_str(&self) -> &'static str {
match self {
SystemKey::Arch => "system_arch",
SystemKey::Date => "system_date",
SystemKey::DirDownload => "system_dir_download",
SystemKey::DirHome => "system_dir_home",
SystemKey::DirPwd => "system_dir_pwd",
SystemKey::DirTemp => "system_dir_temp",
SystemKey::Hostname => "system_hostname",
SystemKey::Language => "system_language",
SystemKey::Os => "system_os",
SystemKey::Pid => "system_pid",
SystemKey::Shell => "system_shell",
SystemKey::Time => "system_time",
SystemKey::User => "system_user",
}
}
pub fn from_str(s: &str) -> Option<Self> {
match s {
"system_arch" => Some(SystemKey::Arch),
"system_date" => Some(SystemKey::Date),
"system_dir_download" => Some(SystemKey::DirDownload),
"system_dir_home" => Some(SystemKey::DirHome),
"system_dir_pwd" => Some(SystemKey::DirPwd),
"system_dir_temp" => Some(SystemKey::DirTemp),
"system_hostname" => Some(SystemKey::Hostname),
"system_language" => Some(SystemKey::Language),
"system_os" => Some(SystemKey::Os),
"system_pid" => Some(SystemKey::Pid),
"system_shell" => Some(SystemKey::Shell),
"system_time" => Some(SystemKey::Time),
"system_user" => Some(SystemKey::User),
_ => None,
}
}
pub fn all() -> &'static [SystemKey] {
&[
SystemKey::Arch,
SystemKey::Date,
SystemKey::DirDownload,
SystemKey::DirHome,
SystemKey::DirPwd,
SystemKey::DirTemp,
SystemKey::Hostname,
SystemKey::Language,
SystemKey::Os,
SystemKey::Pid,
SystemKey::Shell,
SystemKey::Time,
SystemKey::User,
]
}
}
pub trait SystemProvider: Send + Sync {
fn key(&self) -> SystemKey;
fn resolve(&self) -> Result<ContextModel>;
}
pub struct SystemRegistry {
providers: HashMap<SystemKey, Box<dyn SystemProvider>>,
}
impl SystemRegistry {
pub fn new() -> Self {
let mut registry = Self {
providers: HashMap::new(),
};
registry.register(Box::new(SystemArchProvider));
registry.register(Box::new(SystemDateProvider));
registry.register(Box::new(SystemDirDownloadProvider));
registry.register(Box::new(SystemDirHomeProvider));
registry.register(Box::new(SystemDirPwdProvider));
registry.register(Box::new(SystemDirTempProvider));
registry.register(Box::new(SystemHostnameProvider));
registry.register(Box::new(SystemLanguageProvider));
registry.register(Box::new(SystemOsProvider));
registry.register(Box::new(SystemPidProvider));
registry.register(Box::new(SystemShellProvider));
registry.register(Box::new(SystemTimeProvider));
registry.register(Box::new(SystemUserProvider));
registry
}
pub fn register(&mut self, provider: Box<dyn SystemProvider>) {
self.providers.insert(provider.key(), provider);
}
pub fn resolve(&self, key: SystemKey) -> Result<ContextModel> {
match self.providers.get(&key) {
Some(provider) => provider.resolve(),
None => anyhow::bail!("Unknown system tag: '{}'", key.as_str()),
}
}
}