summaryrefslogtreecommitdiff
path: root/src/packages.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/packages.rs')
-rw-r--r--src/packages.rs85
1 files changed, 81 insertions, 4 deletions
diff --git a/src/packages.rs b/src/packages.rs
index 5ee5664..2eadcfc 100644
--- a/src/packages.rs
+++ b/src/packages.rs
@@ -1,19 +1,96 @@
1use std::{fs::File, io::Read};
2
3use pacman::Pacman;
4use portage::Portage;
1use serde::{Deserialize, Serialize}; 5use serde::{Deserialize, Serialize};
2 6
3use crate::error::Result; 7use crate::error::{Error, Result};
4 8
5pub mod pacman; 9#[cfg(feature = "pacman")]
6pub mod portage; 10mod pacman;
11#[cfg(feature = "portage")]
12mod portage;
7 13
8#[derive(Debug, Serialize, Deserialize)] 14#[derive(Debug, Serialize, Deserialize)]
15pub struct PackageList {
16 packages: Vec<Package>,
17 manager: Manager,
18}
19
20impl PackageList {
21 pub fn install(&self) -> Result<()> {
22 self.manager.to_package_manager().install(self.packages.clone())
23 }
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Package { 27pub struct Package {
10 pub id: String, 28 pub id: String,
11 pub version: String, 29 pub version: String,
12 pub explicit: bool, 30 pub explicit: bool,
13} 31}
14 32
33#[derive(Debug, Clone, clap::ValueEnum, Serialize, Deserialize)]
34pub enum Manager {
35 #[cfg(feature = "pacman")]
36 Pacman,
37 #[cfg(feature = "portage")]
38 Portage,
39}
40
41
42impl Manager {
43 pub fn get_manager(manager: Option<Manager>) -> Result<Box<dyn PackageManager>> {
44 #[cfg(not(target_os = "linux"))]
45 {
46 return Err(Error::Unsupported);
47 }
48
49 #[cfg(target_os = "linux")]
50 {
51 if let Some(man) = manager {
52 return Ok(man.to_package_manager());
53 }
54 let mut os_release = File::open("/etc/os-release")?;
55 let mut content = String::new();
56 os_release.read_to_string(&mut content)?;
57
58 let lines: Vec<&str> = content.split('\n').collect();
59 for line in lines {
60 let Some((key, value)) = line.split_once('=') else {
61 continue;
62 };
63 if key == "ID" {
64 return Self::from_str(value);
65 }
66 }
67 Err(Error::Unsupported)
68 }
69 }
70
71 fn from_str(value: &str) -> Result<Box<dyn PackageManager>> {
72 Ok(match value {
73 #[cfg(feature = "pacman")]
74 "arch" => Box::new(Pacman),
75 #[cfg(feature = "portage")]
76 "gentoo" => Box::new(Portage),
77 _ => return Err(Error::Unsupported),
78 })
79 }
80
81 fn to_package_manager(&self) -> Box<dyn PackageManager> {
82 match self {
83 #[cfg(feature = "pacman")]
84 Self::Pacman => Box::new(Pacman),
85 #[cfg(feature = "portage")]
86 Self::Portage => Box::new(Portage),
87 }
88 }
89}
90
91
15pub trait PackageManager { 92pub trait PackageManager {
16 fn get_installed(&self) -> Result<Vec<Package>>; 93 fn get_installed(&self) -> Result<PackageList>;
17 94
18 fn install(&self, pkgs: Vec<Package>) -> Result<()>; 95 fn install(&self, pkgs: Vec<Package>) -> Result<()>;
19} 96}