alpm_ll/
types.rs

1use crate::{utils::*, LIBRARY, Library};
2
3#[cfg(not(feature = "git"))]
4use crate::PgpKey;
5use crate::{
6    Alpm, AlpmList, AlpmListMut, Conflict, Db, Dep, DependMissing, Error, OwnedConflict,
7    OwnedFileConflict, Package, Pkg,
8};
9
10use std::ffi::c_void;
11use std::fmt;
12use std::io::{self, Read};
13use std::marker::PhantomData;
14use std::mem::{transmute, ManuallyDrop};
15use std::os::raw::c_uchar;
16use std::ptr::NonNull;
17use std::slice;
18use std::{cmp::Ordering, ops::Deref};
19
20use _alpm_db_usage_t::*;
21use _alpm_download_event_type_t::*;
22use _alpm_event_type_t::*;
23use _alpm_hook_when_t::*;
24use _alpm_loglevel_t::*;
25use _alpm_pkgfrom_t::*;
26use _alpm_pkgreason_t::*;
27use _alpm_pkgvalidation_t::*;
28use _alpm_progress_t::*;
29use _alpm_question_type_t::*;
30use _alpm_siglevel_t::*;
31use alpm_sys_ll::*;
32
33use bitflags::bitflags;
34
35#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
36#[must_use]
37pub enum FetchResult {
38    Ok,
39    Err,
40    FileExists,
41}
42
43bitflags! {
44    pub struct SigLevel: u32 {
45        const NONE = 0;
46        const PACKAGE = ALPM_SIG_PACKAGE;
47        const PACKAGE_OPTIONAL = ALPM_SIG_PACKAGE_OPTIONAL;
48        const PACKAGE_MARGINAL_OK = ALPM_SIG_PACKAGE_MARGINAL_OK;
49        const PACKAGE_UNKNOWN_OK = ALPM_SIG_PACKAGE_UNKNOWN_OK;
50        const DATABASE = ALPM_SIG_DATABASE;
51        const DATABASE_OPTIONAL = ALPM_SIG_DATABASE_OPTIONAL;
52        const DATABASE_MARGINAL_OK = ALPM_SIG_DATABASE_MARGINAL_OK;
53        const DATABASE_UNKNOWN_OK = ALPM_SIG_DATABASE_UNKNOWN_OK;
54        const USE_DEFAULT = ALPM_SIG_USE_DEFAULT;
55    }
56}
57
58bitflags! {
59    pub struct Usage: u32 {
60        const NONE = 0;
61        const SYNC = ALPM_DB_USAGE_SYNC;
62        const SEARCH = ALPM_DB_USAGE_SEARCH;
63        const INSTALL = ALPM_DB_USAGE_INSTALL;
64        const UPGRADE = ALPM_DB_USAGE_UPGRADE;
65        const ALL = ALPM_DB_USAGE_ALL;
66    }
67}
68
69bitflags! {
70    pub struct LogLevel: u32 {
71        const NONE = 0;
72        const ERROR = ALPM_LOG_ERROR;
73        const WARNING = ALPM_LOG_WARNING;
74        const DEBUG = ALPM_LOG_DEBUG;
75        const FUNCTION = ALPM_LOG_FUNCTION;
76    }
77}
78
79#[repr(u32)]
80#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
81pub enum Progress {
82    AddStart = ALPM_PROGRESS_ADD_START as u32,
83    UpgradeStart = ALPM_PROGRESS_UPGRADE_START as u32,
84    DowngradeStart = ALPM_PROGRESS_DOWNGRADE_START as u32,
85    ReinstallStart = ALPM_PROGRESS_REINSTALL_START as u32,
86    RemoveStart = ALPM_PROGRESS_REMOVE_START as u32,
87    ConflictsStart = ALPM_PROGRESS_CONFLICTS_START as u32,
88    DiskspaceStart = ALPM_PROGRESS_DISKSPACE_START as u32,
89    IntegrityStart = ALPM_PROGRESS_INTEGRITY_START as u32,
90    LoadStart = ALPM_PROGRESS_LOAD_START as u32,
91    KeyringStart = ALPM_PROGRESS_KEYRING_START as u32,
92}
93
94#[repr(u32)]
95#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
96pub enum PackageFrom {
97    File = ALPM_PKG_FROM_FILE as u32,
98    LocalDb = ALPM_PKG_FROM_LOCALDB as u32,
99    SyncDb = ALPM_PKG_FROM_SYNCDB as u32,
100}
101
102#[repr(u32)]
103#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
104pub enum PackageReason {
105    Explicit = ALPM_PKG_REASON_EXPLICIT as u32,
106    Depend = ALPM_PKG_REASON_DEPEND as u32,
107}
108
109bitflags! {
110    pub struct PackageValidation: u32 {
111        const UNKNOWN = ALPM_PKG_VALIDATION_UNKNOWN;
112        const NONE = ALPM_PKG_VALIDATION_NONE;
113        const MD5SUM = ALPM_PKG_VALIDATION_MD5SUM;
114        const SHA256SUM = ALPM_PKG_VALIDATION_SHA256SUM;
115        const SIGNATURE = ALPM_PKG_VALIDATION_SIGNATURE;
116    }
117}
118
119#[repr(u32)]
120#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
121pub enum EventType {
122    CheckDepsStart = ALPM_EVENT_CHECKDEPS_START as u32,
123    CheckDepsDone = ALPM_EVENT_CHECKDEPS_DONE as u32,
124    FileConflictsStart = ALPM_EVENT_FILECONFLICTS_START as u32,
125    FileConflictsDone = ALPM_EVENT_FILECONFLICTS_DONE as u32,
126    ResolveDepsStart = ALPM_EVENT_RESOLVEDEPS_START as u32,
127    ResolveDepsDone = ALPM_EVENT_RESOLVEDEPS_DONE as u32,
128    InterConflictsStart = ALPM_EVENT_INTERCONFLICTS_START as u32,
129    InterConflictsDone = ALPM_EVENT_INTERCONFLICTS_DONE as u32,
130    TransactionStart = ALPM_EVENT_TRANSACTION_START as u32,
131    TransactionDone = ALPM_EVENT_TRANSACTION_DONE as u32,
132    PackageOperationStart = ALPM_EVENT_PACKAGE_OPERATION_START as u32,
133    PackageOperationDone = ALPM_EVENT_PACKAGE_OPERATION_DONE as u32,
134    IntegrityStart = ALPM_EVENT_INTEGRITY_START as u32,
135    IntegrityDone = ALPM_EVENT_INTEGRITY_DONE as u32,
136    LoadStart = ALPM_EVENT_LOAD_START as u32,
137    LoadDone = ALPM_EVENT_LOAD_DONE as u32,
138    ScriptletInfo = ALPM_EVENT_SCRIPTLET_INFO as u32,
139    RetrieveStart = ALPM_EVENT_DB_RETRIEVE_START as u32,
140    RetrieveDone = ALPM_EVENT_DB_RETRIEVE_DONE as u32,
141    RetrieveFailed = ALPM_EVENT_DB_RETRIEVE_FAILED as u32,
142    PkgRetrieveStart = ALPM_EVENT_PKG_RETRIEVE_START as u32,
143    PkgRetrieveDone = ALPM_EVENT_PKG_RETRIEVE_DONE as u32,
144    PkgRetrieveFailed = ALPM_EVENT_PKG_RETRIEVE_FAILED as u32,
145    DiskSpaceStart = ALPM_EVENT_DISKSPACE_START as u32,
146    DiskSpaceDone = ALPM_EVENT_DISKSPACE_DONE as u32,
147    OptDepRemoval = ALPM_EVENT_OPTDEP_REMOVAL as u32,
148    DatabaseMissing = ALPM_EVENT_DATABASE_MISSING as u32,
149    KeyringStart = ALPM_EVENT_KEYRING_START as u32,
150    KeyringDone = ALPM_EVENT_KEYRING_DONE as u32,
151    KeyDownloadStart = ALPM_EVENT_KEY_DOWNLOAD_START as u32,
152    KeyDownloadDone = ALPM_EVENT_KEY_DOWNLOAD_DONE as u32,
153    PacnewCreated = ALPM_EVENT_PACNEW_CREATED as u32,
154    PacsaveCreated = ALPM_EVENT_PACSAVE_CREATED as u32,
155    HookStart = ALPM_EVENT_HOOK_START as u32,
156    HookDone = ALPM_EVENT_HOOK_DONE as u32,
157    HookRunStart = ALPM_EVENT_HOOK_RUN_START as u32,
158    HookRunDone = ALPM_EVENT_HOOK_RUN_DONE as u32,
159}
160
161#[derive(Debug)]
162pub enum PackageOperation<'a> {
163    Install(Package<'a>),
164    Upgrade(Package<'a>, Package<'a>),
165    Reinstall(Package<'a>, Package<'a>),
166    Downgrade(Package<'a>, Package<'a>),
167    Remove(Package<'a>),
168}
169
170pub struct PackageOperationEvent<'a> {
171    handle: ManuallyDrop<Alpm>,
172    inner: *const alpm_event_package_operation_t,
173    marker: PhantomData<&'a ()>,
174}
175
176impl<'a> fmt::Debug for PackageOperationEvent<'a> {
177    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178        f.debug_struct("PackageOperationEvent")
179            .field("operation", &self.operation())
180            .finish()
181    }
182}
183
184pub struct OptDepRemovalEvent<'a> {
185    handle: ManuallyDrop<Alpm>,
186    inner: *const alpm_event_optdep_removal_t,
187    marker: PhantomData<&'a ()>,
188}
189
190impl<'a> fmt::Debug for OptDepRemovalEvent<'a> {
191    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192        f.debug_struct("OptDepRemovalEvent")
193            .field("pkg", &self.pkg())
194            .field("optdep", &self.optdep())
195            .finish()
196    }
197}
198
199pub struct ScriptletInfoEvent<'a> {
200    inner: *const alpm_event_scriptlet_info_t,
201    marker: PhantomData<&'a ()>,
202}
203
204impl<'a> fmt::Debug for ScriptletInfoEvent<'a> {
205    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206        f.debug_struct("ScriptletInfoEvent")
207            .field("line", &self.line())
208            .finish()
209    }
210}
211
212pub struct DatabaseMissingEvent<'a> {
213    inner: *const alpm_event_database_missing_t,
214    marker: PhantomData<&'a ()>,
215}
216
217impl<'a> fmt::Debug for DatabaseMissingEvent<'a> {
218    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219        f.debug_struct("DatabaseMissingEvent")
220            .field("dbname", &self.dbname())
221            .finish()
222    }
223}
224
225pub struct PkgDownloadEvent<'a> {
226    inner: *const alpm_event_pkgdownload_t,
227    marker: PhantomData<&'a ()>,
228}
229
230impl<'a> fmt::Debug for PkgDownloadEvent<'a> {
231    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232        f.debug_struct("PkgDownloadEvent")
233            .field("file", &self.file())
234            .finish()
235    }
236}
237
238pub struct PacnewCreatedEvent<'a> {
239    handle: ManuallyDrop<Alpm>,
240    inner: *const alpm_event_pacnew_created_t,
241    marker: PhantomData<&'a ()>,
242}
243
244impl<'a> fmt::Debug for PacnewCreatedEvent<'a> {
245    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246        f.debug_struct("PacnewCreatedEvent")
247            .field("from_noupgrade", &self.from_noupgrade())
248            .field("oldpkg", &self.oldpkg())
249            .field("oldnew", &self.oldpkg())
250            .field("file", &self.file())
251            .finish()
252    }
253}
254
255pub struct PacsaveCreatedEvent<'a> {
256    handle: ManuallyDrop<Alpm>,
257    inner: *const alpm_event_pacsave_created_t,
258    marker: PhantomData<&'a ()>,
259}
260
261impl<'a> fmt::Debug for PacsaveCreatedEvent<'a> {
262    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
263        f.debug_struct("PacsaveCreatedEvent")
264            .field("oldpkg", &self.oldpkg())
265            .field("file", &self.file())
266            .finish()
267    }
268}
269
270pub struct HookEvent<'a> {
271    inner: *const alpm_event_hook_t,
272    marker: PhantomData<&'a ()>,
273}
274
275impl<'a> fmt::Debug for HookEvent<'a> {
276    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
277        f.debug_struct("HookEvent")
278            .field("when", &self.when())
279            .finish()
280    }
281}
282
283pub struct HookRunEvent<'a> {
284    inner: *const alpm_event_hook_run_t,
285    marker: PhantomData<&'a ()>,
286}
287
288impl<'a> fmt::Debug for HookRunEvent<'a> {
289    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
290        f.debug_struct("HookRunEvent")
291            .field("name", &self.name())
292            .field("desc", &self.desc())
293            .field("position", &self.position())
294            .field("total", &self.total())
295            .finish()
296    }
297}
298
299#[repr(u32)]
300#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
301pub enum HookWhen {
302    PreTransaction = ALPM_HOOK_PRE_TRANSACTION as u32,
303    PostTransaction = ALPM_HOOK_POST_TRANSACTION as u32,
304}
305
306pub struct PkgRetrieveStartEvent<'a> {
307    inner: *const alpm_event_pkg_retrieve_t,
308    marker: PhantomData<&'a ()>,
309}
310
311impl<'a> fmt::Debug for PkgRetrieveStartEvent<'a> {
312    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
313        f.debug_struct("PkgRetrieveStartEvent")
314            .field("num", &self.num())
315            .field("total_size", &self.total_size())
316            .finish()
317    }
318}
319
320pub struct AnyEvent<'a> {
321    inner: *const alpm_event_t,
322    handle: *mut alpm_handle_t,
323    marker: PhantomData<&'a ()>,
324}
325
326impl<'a> fmt::Debug for AnyEvent<'a> {
327    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328        f.debug_struct("AnyEvent")
329            .field("event", &self.event())
330            .finish()
331    }
332}
333
334#[derive(Debug)]
335pub enum Event<'a> {
336    PackageOperation(PackageOperationEvent<'a>),
337    OptDepRemoval(OptDepRemovalEvent<'a>),
338    ScriptletInfo(ScriptletInfoEvent<'a>),
339    DatabaseMissing(DatabaseMissingEvent<'a>),
340    PacnewCreated(PacnewCreatedEvent<'a>),
341    PacsaveCreated(PacsaveCreatedEvent<'a>),
342    Hook(HookEvent<'a>),
343    HookRun(HookRunEvent<'a>),
344    PkgRetrieveStart(PkgRetrieveStartEvent<'a>),
345    PkgRetrieveDone,
346    PkgRetrieveFailed,
347    CheckDepsStart,
348    CheckDepsDone,
349    FileConflictsStart,
350    FileConflictsDone,
351    ResolveDepsStart,
352    ResolveDepsDone,
353    InterConflictsStart,
354    InterConflictsDone,
355    TransactionStart,
356    TransactionDone,
357    IntegrityStart,
358    IntegrityDone,
359    LoadStart,
360    LoadDone,
361    RetrieveStart,
362    RetrieveDone,
363    RetrieveFailed,
364    DiskSpaceStart,
365    DiskSpaceDone,
366    KeyringStart,
367    KeyringDone,
368    KeyDownloadStart,
369    KeyDownloadDone,
370    HookStart,
371    HookDone,
372    HookRunStart,
373    HookRunDone,
374}
375
376impl<'a> AnyEvent<'a> {
377    pub(crate) unsafe fn new(
378        handle: *mut alpm_handle_t,
379        inner: *const alpm_event_t,
380    ) -> AnyEvent<'a> {
381        AnyEvent {
382            handle,
383            inner,
384            marker: PhantomData,
385        }
386    }
387
388    pub fn event(&self) -> Event<'a> {
389        let event = self.inner;
390        let event_type = self.event_type();
391        let handle = unsafe { Alpm::from_ptr(self.handle) };
392        let handle = ManuallyDrop::new(handle);
393
394        match &event_type {
395            EventType::CheckDepsStart => Event::CheckDepsStart,
396            EventType::CheckDepsDone => Event::CheckDepsDone,
397            EventType::FileConflictsStart => Event::FileConflictsStart,
398            EventType::FileConflictsDone => Event::FileConflictsDone,
399            EventType::ResolveDepsStart => Event::ResolveDepsStart,
400            EventType::ResolveDepsDone => Event::ResolveDepsDone,
401            EventType::InterConflictsStart => Event::InterConflictsStart,
402            EventType::InterConflictsDone => Event::InterConflictsDone,
403            EventType::TransactionStart => Event::TransactionStart,
404            EventType::TransactionDone => Event::TransactionDone,
405            EventType::PackageOperationStart => Event::PackageOperation(PackageOperationEvent {
406                handle,
407                inner: unsafe { &(*event).package_operation },
408
409                marker: PhantomData,
410            }),
411            EventType::PackageOperationDone => Event::PackageOperation(PackageOperationEvent {
412                handle,
413                inner: unsafe { &(*event).package_operation },
414                marker: PhantomData,
415            }),
416            EventType::IntegrityStart => Event::IntegrityStart,
417            EventType::IntegrityDone => Event::InterConflictsDone,
418            EventType::LoadStart => Event::LoadStart,
419            EventType::LoadDone => Event::LoadDone,
420            EventType::ScriptletInfo => Event::ScriptletInfo(ScriptletInfoEvent {
421                inner: unsafe { &(*event).scriptlet_info },
422                marker: PhantomData,
423            }),
424            EventType::RetrieveStart => Event::RetrieveStart,
425            EventType::RetrieveDone => Event::RetrieveDone,
426            EventType::RetrieveFailed => Event::RetrieveFailed,
427            EventType::DiskSpaceStart => Event::DiskSpaceStart,
428            EventType::DiskSpaceDone => Event::DiskSpaceDone,
429            EventType::OptDepRemoval => Event::OptDepRemoval(OptDepRemovalEvent {
430                handle,
431                inner: unsafe { &(*event).optdep_removal },
432                marker: PhantomData,
433            }),
434            EventType::DatabaseMissing => Event::DatabaseMissing(DatabaseMissingEvent {
435                inner: unsafe { &(*event).database_missing },
436                marker: PhantomData,
437            }),
438            EventType::KeyringStart => Event::KeyringStart,
439            EventType::KeyringDone => Event::KeyringDone,
440            EventType::KeyDownloadStart => Event::KeyDownloadStart,
441            EventType::KeyDownloadDone => Event::KeyringDone,
442            EventType::PacnewCreated => Event::PacnewCreated(PacnewCreatedEvent {
443                handle,
444                inner: unsafe { &(*event).pacnew_created },
445                marker: PhantomData,
446            }),
447            EventType::PacsaveCreated => Event::PacsaveCreated(PacsaveCreatedEvent {
448                handle,
449                inner: unsafe { &(*event).pacsave_created },
450                marker: PhantomData,
451            }),
452            EventType::HookStart => Event::HookStart,
453            EventType::HookDone => Event::HookDone,
454            EventType::HookRunStart => Event::HookRunStart,
455            EventType::HookRunDone => Event::HookRunDone,
456            EventType::PkgRetrieveStart => Event::PkgRetrieveStart(PkgRetrieveStartEvent {
457                inner: unsafe { &(*event).pkg_retrieve },
458                marker: PhantomData,
459            }),
460            EventType::PkgRetrieveDone => Event::PkgRetrieveDone,
461            EventType::PkgRetrieveFailed => Event::PkgRetrieveFailed,
462        }
463    }
464
465    pub fn event_type(&self) -> EventType {
466        unsafe { transmute((*self.inner).type_) }
467    }
468}
469
470impl<'a> PackageOperationEvent<'a> {
471    pub fn operation(&self) -> PackageOperation {
472        let oldpkg = unsafe { Package::new(&self.handle, (*self.inner).oldpkg) };
473        let newpkg = unsafe { Package::new(&self.handle, (*self.inner).newpkg) };
474
475        let op = unsafe { (*self.inner).operation };
476        match op {
477            alpm_package_operation_t::ALPM_PACKAGE_INSTALL => PackageOperation::Install(newpkg),
478            alpm_package_operation_t::ALPM_PACKAGE_UPGRADE => {
479                PackageOperation::Upgrade(newpkg, oldpkg)
480            }
481            alpm_package_operation_t::ALPM_PACKAGE_REINSTALL => {
482                PackageOperation::Reinstall(newpkg, oldpkg)
483            }
484            alpm_package_operation_t::ALPM_PACKAGE_DOWNGRADE => {
485                PackageOperation::Downgrade(newpkg, oldpkg)
486            }
487            alpm_package_operation_t::ALPM_PACKAGE_REMOVE => PackageOperation::Remove(oldpkg),
488        }
489    }
490}
491
492impl<'a> OptDepRemovalEvent<'a> {
493    pub fn pkg(&self) -> Package {
494        unsafe { Package::new(&self.handle, (*self.inner).pkg) }
495    }
496
497    pub fn optdep(&self) -> Dep {
498        unsafe { Dep::from_ptr((*self.inner).optdep) }
499    }
500}
501
502impl<'a> ScriptletInfoEvent<'a> {
503    pub fn line(&self) -> &str {
504        unsafe { from_cstr((*self.inner).line) }
505    }
506}
507
508impl<'a> DatabaseMissingEvent<'a> {
509    pub fn dbname(&self) -> &str {
510        unsafe { from_cstr((*self.inner).dbname) }
511    }
512}
513
514impl<'a> PkgDownloadEvent<'a> {
515    pub fn file(&self) -> &str {
516        unsafe { from_cstr((*self.inner).file) }
517    }
518}
519
520impl<'a> PacnewCreatedEvent<'a> {
521    #[allow(clippy::wrong_self_convention)]
522    pub fn from_noupgrade(&self) -> bool {
523        unsafe { (*self.inner).from_noupgrade != 0 }
524    }
525
526    pub fn oldpkg(&self) -> Option<Package> {
527        unsafe {
528            (*self.inner).oldpkg.as_ref()?;
529            Some(Package::new(&self.handle, (*self.inner).oldpkg))
530        }
531    }
532
533    pub fn newpkg(&self) -> Option<Package> {
534        unsafe {
535            (*self.inner).newpkg.as_ref()?;
536            Some(Package::new(&self.handle, (*self.inner).newpkg))
537        }
538    }
539
540    pub fn file(&self) -> &str {
541        unsafe { from_cstr((*self.inner).file) }
542    }
543}
544
545impl<'a> PacsaveCreatedEvent<'a> {
546    pub fn oldpkg(&self) -> Option<Package> {
547        unsafe {
548            (*self.inner).oldpkg.as_ref()?;
549            Some(Package::new(&self.handle, (*self.inner).oldpkg))
550        }
551    }
552
553    pub fn file(&self) -> &str {
554        unsafe { from_cstr((*self.inner).file) }
555    }
556}
557
558impl<'a> HookEvent<'a> {
559    pub fn when(&self) -> HookWhen {
560        unsafe { transmute::<alpm_hook_when_t, HookWhen>((*self.inner).when) }
561    }
562}
563
564impl<'a> HookRunEvent<'a> {
565    pub fn name(&self) -> &str {
566        unsafe { from_cstr((*self.inner).name) }
567    }
568
569    pub fn desc(&self) -> &str {
570        unsafe { from_cstr_optional2((*self.inner).desc) }
571    }
572
573    pub fn position(&self) -> usize {
574        unsafe { (*self.inner).position as usize }
575    }
576
577    pub fn total(&self) -> usize {
578        unsafe { (*self.inner).total as usize }
579    }
580}
581
582impl<'a> PkgRetrieveStartEvent<'a> {
583    pub fn num(&self) -> usize {
584        unsafe { (*self.inner).num }
585    }
586
587    #[allow(clippy::useless_conversion)]
588    pub fn total_size(&self) -> i64 {
589        unsafe { (*self.inner).total_size.into() }
590    }
591}
592
593pub struct InstallIgnorepkgQuestion<'a> {
594    handle: ManuallyDrop<Alpm>,
595    inner: *mut alpm_question_install_ignorepkg_t,
596    marker: PhantomData<&'a ()>,
597}
598
599impl<'a> fmt::Debug for InstallIgnorepkgQuestion<'a> {
600    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
601        f.debug_struct("InstallIgnorepkgQuestion")
602            .field("install", &self.install())
603            .field("pkg", &self.pkg())
604            .finish()
605    }
606}
607
608pub struct ReplaceQuestion<'a> {
609    handle: ManuallyDrop<Alpm>,
610    inner: *mut alpm_question_replace_t,
611    marker: PhantomData<&'a ()>,
612}
613
614impl<'a> fmt::Debug for ReplaceQuestion<'a> {
615    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
616        f.debug_struct("ReplaceQuestion")
617            .field("replace", &self.replace())
618            .field("oldpkg", &self.oldpkg())
619            .field("newpkg", &self.newpkg())
620            .field("newdb", &self.newdb())
621            .finish()
622    }
623}
624
625pub struct ConflictQuestion<'a> {
626    inner: *mut alpm_question_conflict_t,
627    marker: PhantomData<&'a ()>,
628}
629
630impl<'a> fmt::Debug for ConflictQuestion<'a> {
631    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
632        f.debug_struct("ConflictQuestion")
633            .field("remove", &self.remove())
634            .field("conflict", &self.conflict())
635            .finish()
636    }
637}
638
639pub struct CorruptedQuestion<'a> {
640    inner: *mut alpm_question_corrupted_t,
641    marker: PhantomData<&'a ()>,
642}
643
644impl<'a> fmt::Debug for CorruptedQuestion<'a> {
645    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
646        f.debug_struct("CorruptedQuestion")
647            .field("remove", &self.remove())
648            .field("filepath", &self.filepath())
649            .field("reason", &self.reason())
650            .finish()
651    }
652}
653
654pub struct RemovePkgsQuestion<'a> {
655    handle: ManuallyDrop<Alpm>,
656    inner: *mut alpm_question_remove_pkgs_t,
657    marker: PhantomData<&'a ()>,
658}
659
660impl<'a> fmt::Debug for RemovePkgsQuestion<'a> {
661    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
662        f.debug_struct("RemovePkgsQuestion")
663            .field("skip", &self.skip())
664            .field("packages", &self.packages())
665            .finish()
666    }
667}
668
669pub struct SelectProviderQuestion<'a> {
670    handle: ManuallyDrop<Alpm>,
671    inner: *mut alpm_question_select_provider_t,
672    marker: PhantomData<&'a ()>,
673}
674
675impl<'a> fmt::Debug for SelectProviderQuestion<'a> {
676    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
677        f.debug_struct("SelectProviderQuestion")
678            .field("index", &self.index())
679            .field("providers", &self.providers())
680            .field("depend", &self.depend())
681            .finish()
682    }
683}
684
685pub struct ImportKeyQuestion<'a> {
686    inner: *mut alpm_question_import_key_t,
687    marker: PhantomData<&'a ()>,
688}
689
690impl<'a> fmt::Debug for ImportKeyQuestion<'a> {
691    #[cfg(not(feature = "git"))]
692    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
693        f.debug_struct("ImportKeyQuestion")
694            .field("import", &self.import())
695            .field("key", &self.key())
696            .finish()
697    }
698
699    #[cfg(feature = "git")]
700    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
701        f.debug_struct("ImportKeyQuestion")
702            .field("import", &self.import())
703            .field("uid", &self.uid())
704            .field("fingerprint", &self.fingerprint())
705            .finish()
706    }
707}
708
709pub struct AnyQuestion<'a> {
710    handle: *mut alpm_handle_t,
711    inner: *mut alpm_question_t,
712    marker: PhantomData<&'a ()>,
713}
714
715impl<'a> fmt::Debug for AnyQuestion<'a> {
716    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
717        f.debug_struct("AnyQuestion")
718            .field("question", &self.question())
719            .finish()
720    }
721}
722
723#[derive(Debug)]
724pub enum Question<'a> {
725    InstallIgnorepkg(InstallIgnorepkgQuestion<'a>),
726    Replace(ReplaceQuestion<'a>),
727    Conflict(ConflictQuestion<'a>),
728    Corrupted(CorruptedQuestion<'a>),
729    RemovePkgs(RemovePkgsQuestion<'a>),
730    SelectProvider(SelectProviderQuestion<'a>),
731    ImportKey(ImportKeyQuestion<'a>),
732}
733
734#[repr(u32)]
735#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
736pub enum QuestionType {
737    InstallIgnorepkg = ALPM_QUESTION_INSTALL_IGNOREPKG as u32,
738    ReplacePkg = ALPM_QUESTION_REPLACE_PKG as u32,
739    ConflictPkg = ALPM_QUESTION_CONFLICT_PKG as u32,
740    CorruptedPkg = ALPM_QUESTION_CORRUPTED_PKG as u32,
741    RemovePkgs = ALPM_QUESTION_REMOVE_PKGS as u32,
742    SelectProvider = ALPM_QUESTION_SELECT_PROVIDER as u32,
743    ImportKey = ALPM_QUESTION_IMPORT_KEY as u32,
744}
745
746impl<'a> AnyQuestion<'a> {
747    pub(crate) unsafe fn new(
748        handle: *mut alpm_handle_t,
749        question: *mut alpm_question_t,
750    ) -> AnyQuestion<'a> {
751        AnyQuestion {
752            inner: question,
753            handle,
754            marker: PhantomData,
755        }
756    }
757
758    pub fn question(&self) -> Question<'a> {
759        let question_type = self.question_type();
760        let handle = unsafe { Alpm::from_ptr(self.handle) };
761        let handle = ManuallyDrop::new(handle);
762
763        match &question_type {
764            QuestionType::InstallIgnorepkg => {
765                Question::InstallIgnorepkg(InstallIgnorepkgQuestion {
766                    handle,
767                    inner: unsafe { &mut (*self.inner).install_ignorepkg },
768                    marker: PhantomData,
769                })
770            }
771            QuestionType::ReplacePkg => Question::Replace(ReplaceQuestion {
772                handle,
773                inner: unsafe { &mut (*self.inner).replace },
774                marker: PhantomData,
775            }),
776            QuestionType::ConflictPkg => Question::Conflict(ConflictQuestion {
777                inner: unsafe { &mut (*self.inner).conflict },
778                marker: PhantomData,
779            }),
780            QuestionType::CorruptedPkg => Question::Corrupted(CorruptedQuestion {
781                inner: unsafe { &mut (*self.inner).corrupted },
782                marker: PhantomData,
783            }),
784            QuestionType::RemovePkgs => Question::RemovePkgs(RemovePkgsQuestion {
785                handle,
786                inner: unsafe { &mut (*self.inner).remove_pkgs },
787                marker: PhantomData,
788            }),
789
790            QuestionType::SelectProvider => Question::SelectProvider(SelectProviderQuestion {
791                handle,
792                inner: unsafe { &mut (*self.inner).select_provider },
793                marker: PhantomData,
794            }),
795            QuestionType::ImportKey => Question::ImportKey(ImportKeyQuestion {
796                inner: unsafe { &mut (*self.inner).import_key },
797                marker: PhantomData,
798            }),
799        }
800    }
801
802    pub fn set_answer(&mut self, answer: bool) {
803        unsafe { (*self.inner).any.answer = answer as _ }
804    }
805
806    pub fn question_type(&self) -> QuestionType {
807        unsafe { transmute((*self.inner).type_) }
808    }
809}
810
811impl<'a> InstallIgnorepkgQuestion<'a> {
812    pub fn set_install(&mut self, install: bool) {
813        unsafe {
814            if install {
815                (*self.inner).install = 1;
816            } else {
817                (*self.inner).install = 0;
818            }
819        }
820    }
821
822    pub fn install(&self) -> bool {
823        unsafe { (*self.inner).install != 0 }
824    }
825
826    pub fn pkg(&self) -> Package {
827        unsafe { Package::new(&self.handle, (*self.inner).pkg) }
828    }
829}
830
831impl<'a> ReplaceQuestion<'a> {
832    pub fn set_replace(&self, replace: bool) {
833        unsafe {
834            if replace {
835                (*self.inner).replace = 1;
836            } else {
837                (*self.inner).replace = 0;
838            }
839        }
840    }
841
842    pub fn replace(&self) -> bool {
843        unsafe { (*self.inner).replace != 0 }
844    }
845
846    pub fn newpkg(&self) -> Package {
847        unsafe { Package::new(&self.handle, (*self.inner).newpkg) }
848    }
849
850    pub fn oldpkg(&self) -> Package {
851        unsafe { Package::new(&self.handle, (*self.inner).oldpkg) }
852    }
853
854    pub fn newdb(&self) -> Db {
855        unsafe { Db::new(&self.handle, (*self.inner).newdb) }
856    }
857}
858
859impl<'a> ConflictQuestion<'a> {
860    pub fn set_remove(&mut self, remove: bool) {
861        unsafe {
862            if remove {
863                (*self.inner).remove = 1;
864            } else {
865                (*self.inner).remove = 0;
866            }
867        }
868    }
869
870    pub fn remove(&self) -> bool {
871        unsafe { (*self.inner).remove != 0 }
872    }
873
874    pub fn conflict(&self) -> Conflict {
875        unsafe { Conflict::from_ptr((*self.inner).conflict) }
876    }
877}
878
879impl<'a> CorruptedQuestion<'a> {
880    pub fn set_remove(&mut self, remove: bool) {
881        unsafe {
882            if remove {
883                (*self.inner).remove = 1;
884            } else {
885                (*self.inner).remove = 0;
886            }
887        }
888    }
889
890    pub fn remove(&self) -> bool {
891        unsafe { (*self.inner).remove != 0 }
892    }
893
894    pub fn filepath(&self) -> &str {
895        unsafe { from_cstr((*self.inner).filepath) }
896    }
897
898    pub fn reason(&self) -> Error {
899        unsafe { Error::new((*self.inner).reason) }
900    }
901}
902
903impl<'a> RemovePkgsQuestion<'a> {
904    pub fn set_skip(&mut self, skip: bool) {
905        unsafe {
906            if skip {
907                (*self.inner).skip = 1;
908            } else {
909                (*self.inner).skip = 0;
910            }
911        }
912    }
913
914    pub fn skip(&self) -> bool {
915        unsafe { (*self.inner).skip != 0 }
916    }
917
918    pub fn packages(&'a self) -> AlpmList<'a, Package> {
919        let list = unsafe { (*self.inner).packages };
920        unsafe { AlpmList::from_parts(&self.handle, list) }
921    }
922}
923
924impl<'a> SelectProviderQuestion<'a> {
925    pub fn set_index(&mut self, index: i32) {
926        unsafe {
927            (*self.inner).use_index = index;
928        }
929    }
930
931    pub fn index(&self) -> i32 {
932        unsafe { (*self.inner).use_index }
933    }
934
935    pub fn providers(&self) -> AlpmList<Package> {
936        let list = unsafe { (*self.inner).providers };
937        unsafe { AlpmList::from_parts(&self.handle, list) }
938    }
939
940    pub fn depend(&self) -> Dep {
941        unsafe { Dep::from_ptr((*self.inner).depend) }
942    }
943}
944
945impl<'a> ImportKeyQuestion<'a> {
946    pub fn set_import(&mut self, import: bool) {
947        unsafe {
948            if import {
949                (*self.inner).import = 1;
950            } else {
951                (*self.inner).import = 0;
952            }
953        }
954    }
955
956    pub fn import(&self) -> bool {
957        unsafe { (*self.inner).import != 0 }
958    }
959
960    #[cfg(feature = "git")]
961    pub fn uid(&self) -> &str {
962        unsafe { from_cstr((*self.inner).uid) }
963    }
964
965    #[cfg(feature = "git")]
966    pub fn fingerprint(&self) -> &str {
967        unsafe { from_cstr((*self.inner).fingerprint) }
968    }
969
970    #[cfg(not(feature = "git"))]
971    pub fn key(&self) -> PgpKey {
972        let key = unsafe { *(*self.inner).key };
973        PgpKey { inner: key }
974    }
975}
976
977pub struct Group<'a> {
978    pub(crate) handle: &'a Alpm,
979    inner: NonNull<alpm_group_t>,
980}
981
982impl<'a> fmt::Debug for Group<'a> {
983    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
984        f.debug_struct("Group")
985            .field("name", &self.name())
986            .field("packages", &self.packages())
987            .finish()
988    }
989}
990
991impl<'a> Group<'a> {
992    pub(crate) unsafe fn new(handle: &Alpm, ptr: *mut alpm_group_t) -> Group {
993        Group {
994            handle,
995            inner: NonNull::new_unchecked(ptr),
996        }
997    }
998
999    pub(crate) fn as_ptr(&self) -> *mut alpm_group_t {
1000        self.inner.as_ptr()
1001    }
1002
1003    pub fn name(&self) -> &'a str {
1004        unsafe { from_cstr((*self.as_ptr()).name) }
1005    }
1006
1007    pub fn packages(&self) -> AlpmList<'a, Package<'a>> {
1008        let pkgs = unsafe { (*self.as_ptr()).packages };
1009        unsafe { AlpmList::from_parts(self.handle, pkgs) }
1010    }
1011}
1012
1013pub struct ChangeLog<'a> {
1014    pub(crate) pkg: Pkg<'a>,
1015    stream: NonNull<c_void>,
1016}
1017
1018impl<'a> fmt::Debug for ChangeLog<'a> {
1019    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1020        f.debug_struct("ChangeLog").field("pkg", &self.pkg).finish()
1021    }
1022}
1023
1024impl<'a> Drop for ChangeLog<'a> {
1025    fn drop(&mut self) {
1026        unsafe { LIBRARY.force_load().alpm_pkg_changelog_close(self.pkg.as_ptr(), self.as_ptr()) };
1027    }
1028}
1029
1030impl<'a> Read for ChangeLog<'a> {
1031    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1032        let ret = unsafe {
1033            LIBRARY.force_load().alpm_pkg_changelog_read(
1034                buf.as_mut_ptr() as *mut c_void,
1035                buf.len(),
1036                self.pkg.as_ptr(),
1037                self.as_ptr(),
1038            )
1039        };
1040        Ok(ret)
1041    }
1042}
1043
1044impl<'a> ChangeLog<'a> {
1045    pub(crate) unsafe fn new(pkg: Pkg, ptr: *mut c_void) -> ChangeLog {
1046        ChangeLog {
1047            pkg,
1048            stream: NonNull::new_unchecked(ptr),
1049        }
1050    }
1051
1052    pub(crate) fn as_ptr(&self) -> *mut c_void {
1053        self.stream.as_ptr()
1054    }
1055}
1056
1057#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
1058pub enum Match {
1059    No,
1060    Yes,
1061    Inverted,
1062}
1063
1064#[derive(Debug)]
1065#[must_use]
1066pub enum PrepareResult<'a> {
1067    PkgInvalidArch(AlpmListMut<'a, Package<'a>>),
1068    UnsatisfiedDeps(AlpmListMut<'a, DependMissing>),
1069    ConflictingDeps(AlpmListMut<'a, OwnedConflict>),
1070    Ok,
1071}
1072
1073#[derive(Debug)]
1074#[must_use]
1075pub enum CommitResult<'a> {
1076    FileConflict(AlpmListMut<'a, OwnedFileConflict>),
1077    PkgInvalid(AlpmListMut<'a, String>),
1078    Ok,
1079}
1080
1081// TODO: unsound: need lifetime on handle
1082#[derive(Copy, Clone)]
1083pub struct Backup {
1084    inner: NonNull<alpm_backup_t>,
1085}
1086
1087impl fmt::Debug for Backup {
1088    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1089        f.debug_struct("Backup")
1090            .field("hash", &self.hash())
1091            .field("name", &self.name())
1092            .finish()
1093    }
1094}
1095
1096impl Backup {
1097    pub(crate) unsafe fn from_ptr(ptr: *mut alpm_backup_t) -> Backup {
1098        Backup {
1099            inner: NonNull::new_unchecked(ptr),
1100        }
1101    }
1102
1103    pub(crate) fn as_ptr(&self) -> *mut alpm_backup_t {
1104        self.inner.as_ptr()
1105    }
1106
1107    pub fn hash(&self) -> &str {
1108        unsafe { from_cstr((*self.as_ptr()).hash) }
1109    }
1110
1111    pub fn name(&self) -> &str {
1112        unsafe { from_cstr((*self.as_ptr()).name) }
1113    }
1114}
1115
1116pub struct AnyDownloadEvent<'a> {
1117    event: alpm_download_event_type_t,
1118    data: *mut c_void,
1119    marker: PhantomData<&'a ()>,
1120}
1121
1122impl<'a> fmt::Debug for AnyDownloadEvent<'a> {
1123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1124        f.debug_struct("AnyDownloadEvent")
1125            .field("event", &self.event())
1126            .finish()
1127    }
1128}
1129
1130#[repr(u32)]
1131#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
1132pub enum DownloadEventType {
1133    Init = ALPM_DOWNLOAD_INIT as u32,
1134    Retry = ALPM_DOWNLOAD_RETRY as u32,
1135    Progress = ALPM_DOWNLOAD_PROGRESS as u32,
1136    Completed = ALPM_DOWNLOAD_COMPLETED as u32,
1137}
1138
1139impl<'a> AnyDownloadEvent<'a> {
1140    pub(crate) unsafe fn new(
1141        event: alpm_download_event_type_t,
1142        data: *mut c_void,
1143    ) -> AnyDownloadEvent<'a> {
1144        AnyDownloadEvent {
1145            event,
1146            data,
1147            marker: PhantomData,
1148        }
1149    }
1150
1151    #[allow(clippy::useless_conversion)]
1152    pub fn event(&self) -> DownloadEvent {
1153        let event = unsafe { transmute(self.event) };
1154        match event {
1155            DownloadEventType::Init => {
1156                let data = self.data as *const alpm_download_event_init_t;
1157                let event = DownloadEventInit {
1158                    optional: unsafe { (*data).optional != 0 },
1159                };
1160                DownloadEvent::Init(event)
1161            }
1162            DownloadEventType::Progress => {
1163                let data = self.data as *const alpm_download_event_progress_t;
1164                let event = DownloadEventProgress {
1165                    downloaded: unsafe { (*data).downloaded.into() },
1166                    total: unsafe { (*data).total.into() },
1167                };
1168                DownloadEvent::Progress(event)
1169            }
1170            DownloadEventType::Retry => {
1171                let data = self.data as *const alpm_download_event_retry_t;
1172                let event = DownloadEventRetry {
1173                    resume: unsafe { (*data).resume != 0 },
1174                };
1175                DownloadEvent::Retry(event)
1176            }
1177            DownloadEventType::Completed => {
1178                let data = self.data as *mut alpm_download_event_completed_t;
1179                let result = match unsafe { (*data).result.cmp(&0) } {
1180                    Ordering::Equal => DownloadResult::Success,
1181                    Ordering::Greater => DownloadResult::UpToDate,
1182                    Ordering::Less => DownloadResult::Failed,
1183                };
1184                let event = DownloadEventCompleted {
1185                    total: unsafe { (*data).total.into() },
1186                    result,
1187                };
1188                DownloadEvent::Completed(event)
1189            }
1190        }
1191    }
1192}
1193
1194#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
1195pub enum DownloadEvent {
1196    Init(DownloadEventInit),
1197    Progress(DownloadEventProgress),
1198    Retry(DownloadEventRetry),
1199    Completed(DownloadEventCompleted),
1200}
1201
1202#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
1203pub struct DownloadEventInit {
1204    pub optional: bool,
1205}
1206
1207#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
1208pub struct DownloadEventProgress {
1209    pub downloaded: i64,
1210    pub total: i64,
1211}
1212
1213#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
1214pub struct DownloadEventRetry {
1215    pub resume: bool,
1216}
1217
1218#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
1219pub struct DownloadEventCompleted {
1220    pub total: i64,
1221    pub result: DownloadResult,
1222}
1223
1224#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd, Hash)]
1225#[must_use]
1226pub enum DownloadResult {
1227    Success,
1228    UpToDate,
1229    Failed,
1230}
1231
1232pub struct Signature {
1233    sig: NonNull<c_uchar>,
1234    len: usize,
1235}
1236
1237impl Signature {
1238    pub(crate) unsafe fn new(sig: *mut c_uchar, len: usize) -> Signature {
1239        Signature {
1240            sig: NonNull::new_unchecked(sig),
1241            len,
1242        }
1243    }
1244
1245    pub(crate) fn as_ptr(&self) -> *mut c_uchar {
1246        self.sig.as_ptr()
1247    }
1248
1249    pub fn sig(&self) -> &[u8] {
1250        unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
1251    }
1252}
1253
1254impl fmt::Debug for Signature {
1255    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1256        f.debug_list().entries(self.sig()).finish()
1257    }
1258}
1259
1260impl Deref for Signature {
1261    type Target = [u8];
1262
1263    fn deref(&self) -> &Self::Target {
1264        self.sig()
1265    }
1266}
1267
1268impl Drop for Signature {
1269    fn drop(&mut self) {
1270        unsafe { crate::free(self.as_ptr() as _) }
1271    }
1272}