1use crate::{Alpm, Error, LoadedPackage, Package};
2
3use alpm_sys_ll::*;
4
5use std::fmt;
6
7pub unsafe trait IntoPkgAdd: fmt::Debug {
8 #[doc(hidden)]
9 unsafe fn as_alpm_pkg_t(&self) -> *mut alpm_pkg_t;
10 #[doc(hidden)]
11 unsafe fn added(self);
12}
13
14unsafe impl<'a> IntoPkgAdd for Package<'a> {
15 unsafe fn as_alpm_pkg_t(&self) -> *mut alpm_pkg_t {
16 self.pkg.as_ptr()
17 }
18 unsafe fn added(self) {}
19}
20unsafe impl<'a> IntoPkgAdd for LoadedPackage<'a> {
21 unsafe fn as_alpm_pkg_t(&self) -> *mut alpm_pkg_t {
22 self.pkg.as_ptr()
23 }
24 unsafe fn added(self) {
25 std::mem::forget(self);
26 }
27}
28
29impl Alpm {
30 pub fn trans_add_pkg<P: IntoPkgAdd>(&self, pkg: P) -> Result<(), AddError<P>> {
31 let ret = unsafe { self.lib.alpm_add_pkg(self.as_ptr(), pkg.as_alpm_pkg_t()) };
32 let ok = self.check_ret(ret);
33 match ok {
34 Ok(_) => {
35 unsafe { pkg.added() };
36 Ok(())
37 }
38 Err(err) => Err(AddError { err, pkg }),
39 }
40 }
41}
42
43#[derive(Debug)]
44pub struct AddError<P> {
45 pub err: Error,
46 pub pkg: P,
47}
48
49impl<P> fmt::Display for AddError<P> {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 fmt::Display::fmt(&self.err, f)
52 }
53}
54
55impl<P: IntoPkgAdd> std::error::Error for AddError<P> {}
56
57impl<P> From<AddError<P>> for Error {
58 fn from(err: AddError<P>) -> Error {
59 err.err
60 }
61}