alpm/
be_pkg.rs

1use crate::{Alpm, Pkg, Result, SigLevel};
2
3use alpm_sys::*;
4
5use std::ffi::CString;
6use std::os::raw::c_int;
7use std::ptr;
8
9#[derive(Debug)]
10pub struct LoadedPackage<'a> {
11    pub(crate) pkg: &'a Pkg,
12}
13
14impl Drop for LoadedPackage<'_> {
15    fn drop(&mut self) {
16        unsafe {
17            alpm_pkg_free(self.pkg.as_ptr());
18        }
19    }
20}
21
22impl std::ops::Deref for LoadedPackage<'_> {
23    type Target = Pkg;
24
25    fn deref(&self) -> &Self::Target {
26        self.pkg
27    }
28}
29
30impl AsRef<Pkg> for LoadedPackage<'_> {
31    fn as_ref(&self) -> &Pkg {
32        self
33    }
34}
35
36impl<'a> LoadedPackage<'a> {
37    pub(crate) unsafe fn from_ptr<'b>(pkg: *mut alpm_pkg_t) -> LoadedPackage<'b> {
38        LoadedPackage {
39            pkg: unsafe { Pkg::from_ptr(pkg) },
40        }
41    }
42
43    pub fn pkg(&'a self) -> &'a Pkg {
44        self.pkg
45    }
46}
47
48impl Alpm {
49    pub fn pkg_load<S: Into<Vec<u8>>>(
50        &self,
51        filename: S,
52        full: bool,
53        level: SigLevel,
54    ) -> Result<LoadedPackage> {
55        let filename = CString::new(filename).unwrap();
56        let mut pkg = ptr::null_mut();
57
58        let ret = unsafe {
59            alpm_pkg_load(
60                self.as_ptr(),
61                filename.as_ptr(),
62                full as c_int,
63                level.bits() as i32,
64                &mut pkg,
65            )
66        };
67        self.check_ret(ret)?;
68        Ok(LoadedPackage {
69            pkg: unsafe { Pkg::from_ptr(pkg) },
70        })
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use crate::Result;
78
79    #[test]
80    fn load() -> Result<()> {
81        let handle = Alpm::new("/", "tests/db").unwrap();
82        let pkg = handle.pkg_load(
83            "tests/pacman-5.1.3-1-x86_64.pkg.tar.xz",
84            false,
85            SigLevel::NONE,
86        )?;
87        assert_eq!(pkg.name(), "pacman");
88        assert_eq!(pkg.version().as_str(), "5.1.3-1");
89        assert_eq!(pkg.base(), Some("pacman"));
90        assert_eq!(
91            pkg.desc(),
92            Some("A library-based package manager with dependency support")
93        );
94        assert_eq!(pkg.url(), Some("https://www.archlinux.org/pacman/"));
95        assert_eq!(pkg.packager(), Some("Allan McRae <allan@archlinux.org>"));
96        assert_eq!(pkg.arch(), Some("x86_64"));
97
98        #[cfg(not(feature = "git"))]
99        assert_eq!(pkg.md5sum(), None);
100
101        assert_eq!(pkg.sha256sum(), None);
102        assert_eq!(pkg.base64_sig(), None);
103
104        Ok(())
105    }
106
107    #[test]
108    fn load_incomplete() {
109        let handle = Alpm::new("/", "tests/db").unwrap();
110        let pkg = handle
111            .pkg_load(
112                "tests/pacman-5.1.3-1-incomplete.pkg.tar.xz",
113                false,
114                SigLevel::NONE,
115            )
116            .unwrap();
117        assert_eq!(pkg.name(), "pacman");
118        assert_eq!(pkg.version().as_str(), "5.1.3-1");
119        assert_eq!(pkg.base(), None);
120        assert_eq!(pkg.desc(), None);
121        assert_eq!(pkg.url(), None);
122        assert_eq!(pkg.packager(), None);
123        assert_eq!(pkg.arch(), None);
124
125        #[cfg(not(feature = "git"))]
126        assert_eq!(pkg.md5sum(), None);
127
128        assert_eq!(pkg.sha256sum(), None);
129        assert_eq!(pkg.base64_sig(), None);
130    }
131}