apt_cache/
lib.rs

1//! # apt-cache
2//!
3//! A rust crate to interface the apt-cache command.
4//!
5//! **Warning:** Will only work on machines with `apt` installed!
6//!
7//! ## Exmaple
8//! ```rust
9//! use apt_cache::Package;
10//!
11//! let git = Package::new("git").unwrap();
12//! let libc = Package::new("libc6").unwrap();
13//! assert!(git.depends().unwrap().contains(&libc))
14//! ```
15
16#![feature(str_strip)]
17pub mod apt;
18
19use std::path::Path;
20use apt::parser::{depends, recommends, search};
21use apt::{apt_cache, AptError};
22use serde::{Deserialize, Serialize};
23use std::io;
24use std::process::{Command, Output};
25
26#[derive(PartialEq, Deserialize, Serialize)]
27pub struct Package {
28    pub name: String,
29}
30
31impl Package {
32    /// Create a new package
33    ///
34    /// Returns Err if package is not in the apt cache.
35    pub fn new<T: AsRef<str>>(s: T) -> Result<Self, AptError> {
36        match apt_cache("search", s.as_ref(), &search) {
37            Some(p) => {
38                if p.contains(&s.as_ref().to_string()) {
39                    Ok(Package { name: s.as_ref().to_string() })
40                } else {
41                    Err(AptError::NotFound(format!(
42                        "The package \"{}\" was not found",
43                        s.as_ref()
44                    )))
45                }
46            }
47            None => Err(AptError::NotFound(format!(
48                "The package \"{}\" was not found",
49                s.as_ref()
50            ))),
51        }
52    }
53
54    /// Get packages marked as depends.
55    pub fn depends(&self) -> Option<Vec<Package>> {
56        apt_cache("depends", self.name.as_str(), &depends).and_then(|v| {
57            Some(
58                v.iter()
59                    .map(|p| Package::new(p).expect("Error parsing dependancy"))
60                    .collect::<Vec<Package>>(),
61            )
62        })
63    }
64
65    /// Get packages marked as recommends.
66    pub fn recommends(&self) -> Option<Vec<Package>> {
67        apt_cache("depends", self.name.as_str(), &recommends).and_then(|v| {
68            Some(
69                v.iter()
70                    .map(|p| Package::new(p).expect("Error parsing dependancy"))
71                    .collect::<Vec<Package>>(),
72            )
73        })
74    }
75
76    pub fn get_source<P: AsRef<Path>>(&self, dest: P) -> io::Result<Output> {
77        Command::new("apt").arg("source").arg(self.name.as_str()).current_dir(dest).output()
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    fn create_pkg() -> Package {
86        Package::new("bash").unwrap()
87    }
88
89    #[test]
90    fn test_depends() {
91        assert!(create_pkg()
92            .depends()
93            .unwrap()
94            .contains(&Package::new("base-files").unwrap()))
95    }
96}