use serde::Serialize; use crate::{Module, ModuleSetup}; use crate::facts::{Facts, os::OsFamily}; use crate::utils::cmd::CmdOutput; use std::boxed::Box; pub mod pacman; use pacman::ArchlinuxPackageManager; pub mod apt; use apt::DebianPackageManager; pub mod builder; pub use builder::PackageArgsBuilder; pub type PackageStatus = (); #[derive(Clone, Debug, Serialize)] pub struct PackageArgs { name: PackageList, state: PackageState, } #[derive(Clone, Debug, Serialize)] pub enum PackageState { Present, Absent, Latest, } #[derive(Debug)] pub struct PackageModule { manager: Manager, args: PackageArgs, } #[derive(Debug)] pub struct NoManager; impl Module for PackageModule> { fn serialize_args(&self) -> serde_json::Value { serde_json::to_value(&self.args).unwrap() } fn module_name(&self) -> &'static str { "package" } fn run(self) -> Result<(), PackageError> { Ok(()) } } impl ModuleSetup for PackageModule { fn with_facts(self, facts: &Facts) -> Box> { let Self { args, .. } = self; let manager: Box = match facts.os.family() { OsFamily::Debian => Box::new(DebianPackageManager), OsFamily::Archlinux => Box::new(ArchlinuxPackageManager), }; Box::new(PackageModule { args, manager, }) } } impl PackageModule { pub fn new() -> PackageArgsBuilder { PackageArgsBuilder::new() } } #[derive(Clone, Debug, Serialize)] pub enum PackageError { IoError(String), CmdFail(CmdOutput), } impl From for PackageError { fn from(e: std::io::Error) -> PackageError { PackageError::IoError(e.to_string()) } } pub trait SpecificPackageManager: std::fmt::Debug { fn name(&self) -> &'static str; fn update(&self) -> Result<(), PackageError>; fn install(&self, list: PackageList) -> Result<(), PackageError>; fn remove(&self, list: PackageList) -> Result<(), PackageError>; } #[derive(Clone, Debug, Serialize)] pub struct PackageList { pub list: Vec, } impl PackageList { pub fn list(&self) -> & [ String ] { &self.list } pub fn add(self, add: T) -> PackageList { let Self { mut list } = self; let extend_with = add.into_package_list(); list.extend(extend_with.list); PackageList { list } } } pub trait IntoPackageList { fn into_package_list(self) -> PackageList; } impl >> IntoPackageList for T { fn into_package_list(self) -> PackageList { PackageList { list: self.into() } } }