Files
pacdef_rust/crates/pacdef/src/backend/mod.rs
T

108 lines
3.3 KiB
Rust

pub mod actual;
pub mod backend_trait;
mod root;
pub mod todo_per_backend;
use std::fmt::Display;
use crate::prelude::*;
use anyhow::{Context, Result};
/// A backend with its associated managed packages
pub struct ManagedBackend {
/// All managed packages for this backend, i.e. all packages
/// under the corresponding section in all group files.
pub packages: Packages,
pub any_backend: AnyBackend,
}
impl ManagedBackend {
/// Get unmanaged packages
///
/// # Errors
///
/// Returns an error if the backend fails to get the explicitly installed packages.
pub fn get_unmanaged_packages_sorted(&self) -> Result<Packages> {
let installed = self
.any_backend
.get_explicitly_installed_packages()
.context("could not get explicitly installed packages")?;
let diff = installed.difference(&self.packages).cloned().collect();
Ok(diff)
}
/// Get missing packages
///
/// # Errors
///
/// Returns an error if the backend fails to get the installed packages.
pub fn get_missing_packages_sorted(&self) -> Result<Packages> {
let installed = self
.any_backend
.get_all_installed_packages()
.context("could not get installed packages")?;
let diff = self.packages.difference(&installed).cloned().collect();
Ok(diff)
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[enum_dispatch::enum_dispatch(Backend)]
pub enum AnyBackend {
#[cfg(feature = "arch")]
Arch(actual::arch::Arch),
#[cfg(feature = "debian")]
Debian(actual::debian::Debian),
Flatpak(Flatpak),
Fedora(Fedora),
Python(Python),
Rust(Rust),
Rustup(Rustup),
Void(Void),
}
impl AnyBackend {
/// Returns an iterator of every variant of backend.
pub fn all(config: &Config) -> impl Iterator<Item = Self> {
vec![
#[cfg(feature = "arch")]
Self::Arch(actual::arch::Arch::new(config)),
#[cfg(feature = "debian")]
Self::Debian(actual::debian::Debian::new()),
Self::Flatpak(Flatpak::new(config)),
Self::Fedora(Fedora::new()),
Self::Python(Python::new(config)),
Self::Rust(Rust::new()),
Self::Rustup(Rustup::new()),
Self::Void(Void::new()),
]
.into_iter()
}
pub fn from_section(section: &str, config: &Config) -> Result<Self> {
match section {
#[cfg(feature = "arch")]
"arch" => Ok(Self::Arch(actual::arch::Arch::new(config))),
#[cfg(feature = "debian")]
"debian" => Ok(Self::Debian(actual::debian::Debian::new())),
"flatpak" => Ok(Self::Flatpak(Flatpak::new(config))),
"fedora" => Ok(Self::Fedora(Fedora::new())),
"python" => Ok(Self::Python(Python::new(config))),
"rust" => Ok(Self::Rust(Rust::new())),
"rustup" => Ok(Self::Rustup(Rustup::new())),
"void" => Ok(Self::Void(Void::new())),
_ => Err(anyhow::anyhow!(
"no matching backend for the section: {section}"
)),
}
}
}
impl Display for AnyBackend {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.backend_info().section)
}
}