Add Package example to main

Add remove method to pacman/apt package managers
This commit is contained in:
selfhoster selfhoster 2023-04-20 17:31:45 +02:00
commit f26f1c1bf2
6 changed files with 94 additions and 15 deletions

View file

@ -28,7 +28,12 @@ impl SpecificPackageManager for DebianPackageManager {
Ok(())
}
fn remove(&self, _list: PackageList) -> Result<(), PackageError> {
todo!()
fn remove(&self, list: PackageList) -> Result<(), PackageError> {
let res = Cmd::new("apt").arg("remove").args(list.list()).run()?;
if ! res.success {
return Err(PackageError::CmdFail(res));
}
Ok(())
}
}

View file

@ -101,3 +101,17 @@ impl PackageArgsBuilder<PackageList, PackageState, Box<dyn SpecificPackageManage
}
}
}
impl PackageArgsBuilder<PackageList, PackageState, NoManager> {
pub fn build(self) -> PackageModule<NoManager> {
let Self { name, state, .. } = self;
PackageModule {
args: PackageArgs {
name,
state,
},
manager: NoManager,
}
}
}

View file

@ -12,7 +12,7 @@ pub mod apt;
use apt::DebianPackageManager;
pub mod builder;
pub use builder::PackageArgsBuilder;
pub use builder::{PackageArgsBuilder, NoManager};
pub type PackageStatus = ();
@ -35,10 +35,6 @@ pub struct PackageModule<Manager> {
args: PackageArgs,
}
#[derive(Debug)]
pub struct NoManager;
impl Module<PackageArgs, (), PackageError> for PackageModule<Box<dyn SpecificPackageManager>> {
fn serialize_args(&self) -> serde_json::Value {
serde_json::to_value(&self.args).unwrap()
@ -49,7 +45,17 @@ impl Module<PackageArgs, (), PackageError> for PackageModule<Box<dyn SpecificPac
}
fn run(self) -> Result<(), PackageError> {
Ok(())
let packages = self.args.name;
match &self.args.state {
PackageState::Present => {
self.manager.install(packages)
}, PackageState::Absent => {
self.manager.remove(packages)
}, PackageState::Latest => {
unimplemented!()
}
}
}
}
@ -117,15 +123,35 @@ impl PackageList {
}
}
/// Turn a stringy value or list of values into an actual package list.
/// Only implemented for &str and &str/String slices because apparently
/// there may be a future implementation that turns a slice of stringy values
/// into a stringy value, resulting in conflicting implementations.
/// https://stackoverflow.com/questions/63136970/how-do-i-work-around-the-upstream-crates-may-add-a-new-impl-of-trait-error
pub trait IntoPackageList {
fn into_package_list(self) -> PackageList;
}
impl <T: Into<Vec<String>>> IntoPackageList for T {
impl IntoPackageList for &str {
fn into_package_list(self) -> PackageList {
PackageList {
list: self.into()
list: vec!(self.to_string()),
}
}
}
impl IntoPackageList for & [ &str ] {
fn into_package_list(self) -> PackageList {
PackageList {
list: self.iter().map(|x| x.to_string()).collect(),
}
}
}
impl IntoPackageList for & [ String ] {
fn into_package_list(self) -> PackageList {
PackageList {
list: self.to_vec(),
}
}
}

View file

@ -31,6 +31,12 @@ impl SpecificPackageManager for ArchlinuxPackageManager {
}
fn remove(&self, _list: PackageList) -> Result<(), PackageError> {
todo!()
let res = Cmd::new("pacman").arg("-R").args(list.list()).run()?;
if ! res.success {
return Err(PackageError::CmdFail(res));
}
Ok(())
}
}