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}