alpm_ll/
be_pkg.rs

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