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#[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}