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
28impl<'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}