From 3ffbe28c289a97f76cd37cee54b187de391d1064 Mon Sep 17 00:00:00 2001 From: timeshifter Date: Thu, 12 Jan 2023 23:16:31 +0100 Subject: [PATCH] refactor backend module --- src/backend/backend_trait.rs | 82 ++++++++++++++++++++++++++ src/backend/iter.rs | 21 +++++++ src/backend/mod.rs | 110 ++--------------------------------- src/backend/pacman.rs | 3 +- src/backend/rust.rs | 3 +- src/backend/types.rs | 2 + 6 files changed, 115 insertions(+), 106 deletions(-) create mode 100644 src/backend/backend_trait.rs create mode 100644 src/backend/iter.rs create mode 100644 src/backend/types.rs diff --git a/src/backend/backend_trait.rs b/src/backend/backend_trait.rs new file mode 100644 index 0000000..d851796 --- /dev/null +++ b/src/backend/backend_trait.rs @@ -0,0 +1,82 @@ +use std::collections::HashSet; +use std::os::unix::process::CommandExt; +use std::process::Command; + +use anyhow::{Context, Result}; + +use crate::{Group, Package}; + +use super::types::{Switches, Text}; + +pub(crate) trait Backend { + fn get_binary(&self) -> Text; + fn get_section(&self) -> Text; + fn get_switches_install(&self) -> Switches; + fn get_switches_remove(&self) -> Switches; + fn get_managed_packages(&self) -> &HashSet; + fn load(&mut self, groups: &HashSet); + + /// Get all packages that are installed in the system. + fn get_all_installed_packages(&self) -> Result>; + + /// Get all packages that were installed in the system explicitly. + fn get_explicitly_installed_packages(&self) -> Result>; + + /// Install the specified packages. + fn install_packages(&self, packages: &[Package]) { + if packages.is_empty() { + return; + } + + let mut cmd = Command::new(self.get_binary()); + cmd.args(self.get_switches_install()); + for p in packages { + cmd.arg(format!("{p}")); + } + cmd.exec(); + } + + /// Remove the specified packages. + fn remove_packages(&self, packages: Vec) { + let mut cmd = Command::new(self.get_binary()); + cmd.args(self.get_switches_remove()); + for p in packages { + cmd.arg(format!("{p}")); + } + cmd.exec(); + } + + /// extract packages from its own section as read from group files + fn extract_packages_from_group_file_content(&self, content: &str) -> HashSet { + content + .lines() + .skip_while(|line| !line.starts_with(&format!("[{}]", self.get_section()))) + .skip(1) + .filter(|line| !line.starts_with('[')) + .fuse() + .filter_map(Package::try_from) + .collect() + } + + fn get_missing_packages_sorted(&self) -> Result> { + let installed = self + .get_all_installed_packages() + .context("could not get installed packages")?; + let managed = self.get_managed_packages(); + let mut diff: Vec<_> = managed.difference(&installed).cloned().collect(); + diff.sort_unstable(); + Ok(diff) + } + + fn add_packages(&mut self, packages: HashSet); + + fn get_unmanaged_packages_sorted(&self) -> Result> { + let installed = self + .get_explicitly_installed_packages() + .context("could not get explicitly installed packages")?; + let required = self.get_managed_packages(); + let mut diff: Vec<_> = installed.difference(required).cloned().collect(); + diff.sort_unstable(); + Ok(diff) + } +} diff --git a/src/backend/iter.rs b/src/backend/iter.rs new file mode 100644 index 0000000..0b803ea --- /dev/null +++ b/src/backend/iter.rs @@ -0,0 +1,21 @@ +use super::{Backend, Backends}; + +#[derive(Debug)] +pub(crate) struct BackendIter { + pub(crate) next: Option, +} + +impl Iterator for BackendIter { + type Item = Box; + + fn next(&mut self) -> Option { + match &self.next { + None => None, + Some(b) => { + let result = b.get_backend(); + self.next = b.next(); + Some(result) + } + } + } +} diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 4f6344d..3df36a1 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,117 +1,19 @@ +mod backend_trait; +mod iter; mod macros; mod pacman; mod rust; mod todo_per_backend; +mod types; -use std::collections::HashSet; -use std::os::unix::process::CommandExt; -use std::process::Command; - -use anyhow::{Context, Result}; - -use crate::{Group, Package}; -use pacdef_macro::Register; - +pub(crate) use backend_trait::Backend; +pub(crate) use iter::BackendIter; pub(crate) use todo_per_backend::ToDoPerBackend; -pub(in crate::backend) type Switches = &'static [&'static str]; -pub(in crate::backend) type Text = &'static str; +use pacdef_macro::Register; #[derive(Debug, Register)] pub(crate) enum Backends { Pacman, Rust, } - -#[derive(Debug)] -pub(crate) struct BackendIter { - next: Option, -} - -impl Iterator for BackendIter { - type Item = Box; - - fn next(&mut self) -> Option { - match &self.next { - None => None, - Some(b) => { - let result = b.get_backend(); - self.next = b.next(); - Some(result) - } - } - } -} - -pub(crate) trait Backend { - fn get_binary(&self) -> Text; - fn get_section(&self) -> Text; - fn get_switches_install(&self) -> Switches; - fn get_switches_remove(&self) -> Switches; - fn get_managed_packages(&self) -> &HashSet; - fn load(&mut self, groups: &HashSet); - - /// Get all packages that are installed in the system. - fn get_all_installed_packages(&self) -> Result>; - - /// Get all packages that were installed in the system explicitly. - fn get_explicitly_installed_packages(&self) -> Result>; - - /// Install the specified packages. - fn install_packages(&self, packages: &[Package]) { - if packages.is_empty() { - return; - } - - let mut cmd = Command::new(self.get_binary()); - cmd.args(self.get_switches_install()); - for p in packages { - cmd.arg(format!("{p}")); - } - cmd.exec(); - } - - /// Remove the specified packages. - fn remove_packages(&self, packages: Vec) { - let mut cmd = Command::new(self.get_binary()); - cmd.args(self.get_switches_remove()); - for p in packages { - cmd.arg(format!("{p}")); - } - cmd.exec(); - } - - /// extract packages from its own section as read from group files - fn extract_packages_from_group_file_content(&self, content: &str) -> HashSet { - content - .lines() - .skip_while(|line| !line.starts_with(&format!("[{}]", self.get_section()))) - .skip(1) - .filter(|line| !line.starts_with('[')) - .fuse() - .filter_map(Package::try_from) - .collect() - } - - fn get_missing_packages_sorted(&self) -> Result> { - let installed = self - .get_all_installed_packages() - .context("could not get installed packages")?; - let managed = self.get_managed_packages(); - let mut diff: Vec<_> = managed.difference(&installed).cloned().collect(); - diff.sort_unstable(); - Ok(diff) - } - - fn add_packages(&mut self, packages: HashSet); - - fn get_unmanaged_packages_sorted(&self) -> Result> { - let installed = self - .get_explicitly_installed_packages() - .context("could not get explicitly installed packages")?; - let required = self.get_managed_packages(); - let mut diff: Vec<_> = installed.difference(required).cloned().collect(); - diff.sort_unstable(); - Ok(diff) - } -} diff --git a/src/backend/pacman.rs b/src/backend/pacman.rs index ccd2986..3781686 100644 --- a/src/backend/pacman.rs +++ b/src/backend/pacman.rs @@ -4,7 +4,8 @@ use alpm::Alpm; use alpm::PackageReason::Explicit; use anyhow::{Context, Result}; -use super::{Backend, Switches, Text}; +use super::types::{Switches, Text}; +use super::Backend; use crate::{impl_backend_constants, Group, Package}; pub(crate) struct Pacman { diff --git a/src/backend/rust.rs b/src/backend/rust.rs index 12d3aae..fea1624 100644 --- a/src/backend/rust.rs +++ b/src/backend/rust.rs @@ -5,7 +5,8 @@ use std::path::PathBuf; use anyhow::{Context, Result}; use serde_json::Value; -use super::{Backend, Switches, Text}; +use super::types::{Switches, Text}; +use super::Backend; use crate::{impl_backend_constants, Group, Package}; pub(crate) struct Rust { diff --git a/src/backend/types.rs b/src/backend/types.rs new file mode 100644 index 0000000..740e9e2 --- /dev/null +++ b/src/backend/types.rs @@ -0,0 +1,2 @@ +pub(in crate::backend) type Switches = &'static [&'static str]; +pub(in crate::backend) type Text = &'static str;