rust_apt/cache.rs
1//! Contains Cache related structs.
2
3use std::cell::OnceCell;
4use std::fs;
5use std::path::Path;
6
7use cxx::{Exception, UniquePtr};
8
9use crate::Package;
10use crate::config::{Config, init_config_system};
11use crate::depcache::DepCache;
12use crate::error::{AptErrors, pending_error};
13use crate::pkgmanager::raw::OrderResult;
14use crate::progress::{AcquireProgress, InstallProgress, OperationProgress};
15use crate::raw::{
16 IntoRawIter, IterPkgIterator, PackageManager, PkgCacheFile, PkgIterator, ProblemResolver,
17 create_cache, create_pkgmanager, create_problem_resolver,
18};
19use crate::records::{PackageRecords, SourceRecords};
20use crate::util::{apt_lock, apt_unlock, apt_unlock_inner};
21
22/// Selection of Upgrade type
23#[repr(i32)]
24#[derive(Clone, Debug)]
25pub enum Upgrade {
26 /// Upgrade will Install new and Remove packages in addition to
27 /// upgrading them.
28 ///
29 /// Equivalent to `apt full-upgrade` and `apt-get dist-upgrade`.
30 FullUpgrade = 0,
31 /// Upgrade will Install new but not Remove packages.
32 ///
33 /// Equivalent to `apt upgrade`.
34 Upgrade = 1,
35 /// Upgrade will Not Install new or Remove packages.
36 ///
37 /// Equivalent to `apt-get upgrade`.
38 SafeUpgrade = 3,
39}
40
41/// Selection of how to sort
42enum Sort {
43 /// Disable the sort method.
44 Disable,
45 /// Enable the sort method.
46 Enable,
47 /// Reverse the sort method.
48 Reverse,
49}
50
51/// Determines how to sort packages from the Cache.
52pub struct PackageSort {
53 names: bool,
54 upgradable: Sort,
55 virtual_pkgs: Sort,
56 installed: Sort,
57 auto_installed: Sort,
58 auto_removable: Sort,
59}
60
61impl Default for PackageSort {
62 fn default() -> PackageSort {
63 PackageSort {
64 names: false,
65 upgradable: Sort::Disable,
66 virtual_pkgs: Sort::Disable,
67 installed: Sort::Disable,
68 auto_installed: Sort::Disable,
69 auto_removable: Sort::Disable,
70 }
71 }
72}
73
74impl PackageSort {
75 /// Packages will be sorted by their names a -> z.
76 pub fn names(mut self) -> Self {
77 self.names = true;
78 self
79 }
80
81 /// Only packages that are upgradable will be included.
82 pub fn upgradable(mut self) -> Self {
83 self.upgradable = Sort::Enable;
84 self
85 }
86
87 /// Only packages that are NOT upgradable will be included.
88 pub fn not_upgradable(mut self) -> Self {
89 self.upgradable = Sort::Reverse;
90 self
91 }
92
93 /// Virtual packages will be included.
94 pub fn include_virtual(mut self) -> Self {
95 self.virtual_pkgs = Sort::Enable;
96 self
97 }
98
99 /// Only Virtual packages will be included.
100 pub fn only_virtual(mut self) -> Self {
101 self.virtual_pkgs = Sort::Reverse;
102 self
103 }
104
105 /// Only packages that are installed will be included.
106 pub fn installed(mut self) -> Self {
107 self.installed = Sort::Enable;
108 self
109 }
110
111 /// Only packages that are NOT installed will be included.
112 pub fn not_installed(mut self) -> Self {
113 self.installed = Sort::Reverse;
114 self
115 }
116
117 /// Only packages that are auto installed will be included.
118 pub fn auto_installed(mut self) -> Self {
119 self.auto_installed = Sort::Enable;
120 self
121 }
122
123 /// Only packages that are manually installed will be included.
124 pub fn manually_installed(mut self) -> Self {
125 self.auto_installed = Sort::Reverse;
126 self.installed = Sort::Enable;
127 self
128 }
129
130 /// Only packages that are auto removable will be included.
131 pub fn auto_removable(mut self) -> Self {
132 self.auto_removable = Sort::Enable;
133 self
134 }
135
136 /// Only packages that are NOT auto removable will be included.
137 pub fn not_auto_removable(mut self) -> Self {
138 self.auto_removable = Sort::Reverse;
139 self
140 }
141}
142
143/// The main struct for accessing any and all `apt` data.
144pub struct Cache {
145 pub(crate) ptr: UniquePtr<PkgCacheFile>,
146 depcache: OnceCell<DepCache>,
147 records: OnceCell<PackageRecords>,
148 source_records: OnceCell<SourceRecords>,
149 pkgmanager: OnceCell<UniquePtr<PackageManager>>,
150 problem_resolver: OnceCell<UniquePtr<ProblemResolver>>,
151 local_debs: Vec<String>,
152}
153
154impl Cache {
155 /// Initialize the configuration system, open and return the cache.
156 /// This is the entry point for all operations of this crate.
157 ///
158 /// `local_files` allows you to temporarily add local files to the cache, as
159 /// long as they are one of the following:
160 ///
161 /// - `*.deb` or `*.ddeb` files
162 /// - `Packages` and `Sources` files from apt repositories. These files can
163 /// be compressed.
164 /// - `*.dsc` or `*.changes` files
165 /// - A valid directory containing the file `./debian/control`
166 ///
167 /// This function returns an [`AptErrors`] if any of the files cannot
168 /// be found or are invalid.
169 ///
170 /// Note that if you run [`Cache::commit`] or [`Cache::update`],
171 /// You will be required to make a new cache to perform any further changes
172 pub fn new<T: AsRef<str>>(local_files: &[T]) -> Result<Cache, AptErrors> {
173 let volatile_files: Vec<_> = local_files.iter().map(|d| d.as_ref()).collect();
174
175 init_config_system();
176 Ok(Cache {
177 ptr: create_cache(&volatile_files)?,
178 depcache: OnceCell::new(),
179 records: OnceCell::new(),
180 source_records: OnceCell::new(),
181 pkgmanager: OnceCell::new(),
182 problem_resolver: OnceCell::new(),
183 local_debs: volatile_files
184 .into_iter()
185 .filter(|f| f.ends_with(".deb"))
186 .map(|f| f.to_string())
187 .collect(),
188 })
189 }
190
191 /// Internal Method for generating the package list.
192 pub fn raw_pkgs(&self) -> impl Iterator<Item = UniquePtr<PkgIterator>> {
193 unsafe { self.begin().raw_iter() }
194 }
195
196 /// Get the DepCache
197 pub fn depcache(&self) -> &DepCache {
198 self.depcache
199 .get_or_init(|| DepCache::new(unsafe { self.create_depcache() }))
200 }
201
202 /// Get the PkgRecords
203 pub fn records(&self) -> &PackageRecords {
204 self.records
205 .get_or_init(|| PackageRecords::new(unsafe { self.create_records() }))
206 }
207
208 /// Get the PkgRecords
209 pub fn source_records(&self) -> Result<&SourceRecords, AptErrors> {
210 if let Some(records) = self.source_records.get() {
211 return Ok(records);
212 }
213
214 match unsafe { self.ptr.source_records() } {
215 Ok(raw_records) => {
216 self.source_records
217 .set(SourceRecords::new(raw_records))
218 // Unwrap: This is verified empty at the beginning.
219 .unwrap_or_default();
220 // Unwrap: Records was just added above.
221 Ok(self.source_records.get().unwrap())
222 },
223 Err(_) => Err(AptErrors::new()),
224 }
225 }
226
227 /// Get the PkgManager
228 pub fn pkg_manager(&self) -> &PackageManager {
229 self.pkgmanager
230 .get_or_init(|| unsafe { create_pkgmanager(self.depcache()) })
231 }
232
233 /// Get the ProblemResolver
234 pub fn resolver(&self) -> &ProblemResolver {
235 self.problem_resolver
236 .get_or_init(|| unsafe { create_problem_resolver(self.depcache()) })
237 }
238
239 /// Iterate through the packages in a random order
240 pub fn iter(&self) -> CacheIter<'_> {
241 CacheIter {
242 pkgs: unsafe { self.begin().raw_iter() },
243 cache: self,
244 }
245 }
246
247 /// An iterator of packages in the cache.
248 pub fn packages(&self, sort: &PackageSort) -> impl Iterator<Item = Package<'_>> {
249 let mut pkg_list = vec![];
250 for pkg in self.raw_pkgs() {
251 match sort.virtual_pkgs {
252 // Virtual packages are enabled, include them.
253 // This works differently than the rest. I should probably change defaults.
254 Sort::Enable => {},
255 // If disabled and pkg has no versions, exclude
256 Sort::Disable => {
257 if unsafe { pkg.versions().end() } {
258 continue;
259 }
260 },
261 // If reverse and the package has versions, exclude
262 // This section is for if you only want virtual packages
263 Sort::Reverse => {
264 if unsafe { !pkg.versions().end() } {
265 continue;
266 }
267 },
268 }
269
270 match sort.upgradable {
271 // Virtual packages are enabled, include them.
272 Sort::Disable => {},
273 // If disabled and pkg has no versions, exclude
274 Sort::Enable => {
275 // If the package isn't installed, then it can not be upgradable
276 if unsafe { pkg.current_version().end() }
277 || !self.depcache().is_upgradable(&pkg)
278 {
279 continue;
280 }
281 },
282 // If reverse and the package is installed and upgradable, exclude
283 // This section is for if you only want packages that are not upgradable
284 Sort::Reverse => {
285 if unsafe { !pkg.current_version().end() }
286 && self.depcache().is_upgradable(&pkg)
287 {
288 continue;
289 }
290 },
291 }
292
293 match sort.installed {
294 // Installed Package is Disabled, so we keep them
295 Sort::Disable => {},
296 Sort::Enable => {
297 if unsafe { pkg.current_version().end() } {
298 continue;
299 }
300 },
301 // Only include installed packages.
302 Sort::Reverse => {
303 if unsafe { !pkg.current_version().end() } {
304 continue;
305 }
306 },
307 }
308
309 match sort.auto_installed {
310 // Installed Package is Disabled, so we keep them
311 Sort::Disable => {},
312 Sort::Enable => {
313 if !self.depcache().is_auto_installed(&pkg) {
314 continue;
315 }
316 },
317 // Only include installed packages.
318 Sort::Reverse => {
319 if self.depcache().is_auto_installed(&pkg) {
320 continue;
321 }
322 },
323 }
324
325 match sort.auto_removable {
326 // auto_removable is Disabled, so we keep them
327 Sort::Disable => {},
328 // If the package is not auto removable skip it.
329 Sort::Enable => {
330 // If the Package isn't auto_removable skip
331 if !self.depcache().is_garbage(&pkg) {
332 continue;
333 }
334 },
335 // If the package is auto removable skip it.
336 Sort::Reverse => {
337 if self.depcache().is_garbage(&pkg) {
338 continue;
339 }
340 },
341 }
342
343 // If this is reached we're clear to include the package.
344 pkg_list.push(pkg);
345 }
346
347 if sort.names {
348 pkg_list.sort_by_cached_key(|pkg| pkg.name().to_string());
349 }
350
351 pkg_list.into_iter().map(|pkg| Package::new(self, pkg))
352 }
353
354 /// Updates the package cache and returns a Result
355 ///
356 /// Here is an example of how you may parse the Error messages.
357 ///
358 /// ```
359 /// use rust_apt::new_cache;
360 /// use rust_apt::progress::AcquireProgress;
361 ///
362 /// let cache = new_cache!().unwrap();
363 /// let mut progress = AcquireProgress::apt();
364 /// if let Err(e) = cache.update(&mut progress) {
365 /// for error in e.iter() {
366 /// if error.is_error {
367 /// println!("Error: {}", error.msg);
368 /// } else {
369 /// println!("Warning: {}", error.msg);
370 /// }
371 /// }
372 /// }
373 /// ```
374 /// # Known Errors:
375 /// * E:Could not open lock file /var/lib/apt/lists/lock - open (13:
376 /// Permission denied)
377 /// * E:Unable to lock directory /var/lib/apt/lists/
378 pub fn update(self, progress: &mut AcquireProgress) -> Result<(), AptErrors> {
379 Ok(self.ptr.update(progress.mut_status())?)
380 }
381
382 /// Mark all packages for upgrade
383 ///
384 /// # Example:
385 ///
386 /// ```
387 /// use rust_apt::new_cache;
388 /// use rust_apt::cache::Upgrade;
389 ///
390 /// let cache = new_cache!().unwrap();
391 ///
392 /// cache.upgrade(Upgrade::FullUpgrade).unwrap();
393 /// ```
394 pub fn upgrade(&self, upgrade_type: Upgrade) -> Result<(), AptErrors> {
395 let mut progress = OperationProgress::quiet();
396 Ok(self
397 .depcache()
398 .upgrade(progress.pin().as_mut(), upgrade_type as i32)?)
399 }
400
401 /// Resolve dependencies with the changes marked on all packages. This marks
402 /// additional packages for installation/removal to satisfy the dependency
403 /// chain.
404 ///
405 /// Note that just running a `mark_*` function on a package doesn't
406 /// guarantee that the selected state will be kept during dependency
407 /// resolution. If you need such, make sure to run
408 /// [`crate::Package::protect`] after marking your requested
409 /// modifications.
410 ///
411 /// If `fix_broken` is set to [`true`], the library will try to repair
412 /// broken dependencies of installed packages.
413 ///
414 /// Returns [`Err`] if there was an error reaching dependency resolution.
415 #[allow(clippy::result_unit_err)]
416 pub fn resolve(&self, fix_broken: bool) -> Result<(), AptErrors> {
417 Ok(self
418 .resolver()
419 .resolve(fix_broken, OperationProgress::quiet().pin().as_mut())?)
420 }
421
422 /// Autoinstall every broken package and run the problem resolver
423 /// Returns false if the problem resolver fails.
424 ///
425 /// # Example:
426 ///
427 /// ```
428 /// use rust_apt::new_cache;
429 ///
430 /// let cache = new_cache!().unwrap();
431 ///
432 /// cache.fix_broken();
433 ///
434 /// for pkg in cache.get_changes(false) {
435 /// println!("Pkg Name: {}", pkg.name())
436 /// }
437 /// ```
438 pub fn fix_broken(&self) -> bool { self.depcache().fix_broken() }
439
440 /// Fetch any archives needed to complete the transaction.
441 ///
442 /// # Returns:
443 /// * A [`Result`] enum: the [`Ok`] variant if fetching succeeded, and
444 /// [`Err`] if there was an issue.
445 ///
446 /// # Example:
447 /// ```
448 /// use rust_apt::new_cache;
449 /// use rust_apt::progress::AcquireProgress;
450 ///
451 /// let cache = new_cache!().unwrap();
452 /// let pkg = cache.get("neovim").unwrap();
453 /// let mut progress = AcquireProgress::apt();
454 ///
455 /// pkg.mark_install(true, true);
456 /// pkg.protect();
457 /// cache.resolve(true).unwrap();
458 ///
459 /// cache.get_archives(&mut progress).unwrap();
460 /// ```
461 /// # Known Errors:
462 /// * W:Problem unlinking the file
463 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
464 /// PrepareFiles (13: Permission denied)
465 /// * W:Problem unlinking the file
466 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
467 /// PrepareFiles (13: Permission denied)
468 /// * W:Problem unlinking the file
469 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
470 /// PrepareFiles (13: Permission denied)
471 /// * W:Problem unlinking the file
472 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
473 /// PrepareFiles (13: Permission denied)
474 /// * W:Problem unlinking the file
475 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
476 /// PrepareFiles (13: Permission denied)
477 /// * W:Problem unlinking the file /var/log/apt/eipp.log.xz - FileFd::Open
478 /// (13: Permission denied)
479 /// * W:Could not open file /var/log/apt/eipp.log.xz - open (17: File
480 /// exists)
481 /// * W:Could not open file '/var/log/apt/eipp.log.xz' - EIPP::OrderInstall
482 /// (17: File exists)
483 /// * E:Internal Error, ordering was unable to handle the media swap"
484 pub fn get_archives(&self, progress: &mut AcquireProgress) -> Result<(), Exception> {
485 self.pkg_manager()
486 .get_archives(&self.ptr, self.records(), progress.mut_status())
487 }
488
489 /// Install, remove, and do any other actions requested by the cache.
490 ///
491 /// # Returns:
492 /// * A [`Result`] enum: the [`Ok`] variant if transaction was successful,
493 /// and [`Err`] if there was an issue.
494 ///
495 /// # Example:
496 /// ```
497 /// use rust_apt::new_cache;
498 /// use rust_apt::progress::{AcquireProgress, InstallProgress};
499 ///
500 /// let cache = new_cache!().unwrap();
501 /// let pkg = cache.get("neovim").unwrap();
502 /// let mut acquire_progress = AcquireProgress::apt();
503 /// let mut install_progress = InstallProgress::apt();
504 ///
505 /// pkg.mark_install(true, true);
506 /// pkg.protect();
507 /// cache.resolve(true).unwrap();
508 ///
509 /// // These need root
510 /// // cache.get_archives(&mut acquire_progress).unwrap();
511 /// // cache.do_install(&mut install_progress).unwrap();
512 /// ```
513 ///
514 /// # Known Errors:
515 /// * W:Problem unlinking the file /var/log/apt/eipp.log.xz - FileFd::Open
516 /// (13: Permission denied)
517 /// * W:Could not open file /var/log/apt/eipp.log.xz - open (17: File
518 /// exists)
519 /// * W:Could not open file '/var/log/apt/eipp.log.xz' - EIPP::OrderInstall
520 /// (17: File exists)
521 /// * E:Could not create temporary file for /var/lib/apt/extended_states -
522 /// mkstemp (13: Permission denied)
523 /// * E:Failed to write temporary StateFile /var/lib/apt/extended_states
524 /// * W:Could not open file '/var/log/apt/term.log' - OpenLog (13:
525 /// Permission denied)
526 /// * E:Sub-process /usr/bin/dpkg returned an error code (2)
527 /// * W:Problem unlinking the file /var/cache/apt/pkgcache.bin -
528 /// pkgDPkgPM::Go (13: Permission denied)
529 pub fn do_install(self, progress: &mut InstallProgress) -> Result<(), AptErrors> {
530 let res = match progress {
531 InstallProgress::Fancy(inner) => self.pkg_manager().do_install(inner.pin().as_mut()),
532 InstallProgress::Fd(fd) => self.pkg_manager().do_install_fd(*fd),
533 };
534
535 if pending_error() {
536 return Err(AptErrors::new());
537 }
538
539 match res {
540 OrderResult::Completed => {},
541 OrderResult::Failed => panic!(
542 "DoInstall failed with no error from libapt. Please report this as an issue."
543 ),
544 OrderResult::Incomplete => {
545 panic!("Result is 'Incomplete', please request media swapping as a feature.")
546 },
547 _ => unreachable!(),
548 }
549
550 Ok(())
551 }
552
553 /// Handle get_archives and do_install in an easy wrapper.
554 ///
555 /// # Returns:
556 /// * A [`Result`]: the [`Ok`] variant if transaction was successful, and
557 /// [`Err`] if there was an issue.
558 /// # Example:
559 /// ```
560 /// use rust_apt::new_cache;
561 /// use rust_apt::progress::{AcquireProgress, InstallProgress};
562 ///
563 /// let cache = new_cache!().unwrap();
564 /// let pkg = cache.get("neovim").unwrap();
565 /// let mut acquire_progress = AcquireProgress::apt();
566 /// let mut install_progress = InstallProgress::apt();
567 ///
568 /// pkg.mark_install(true, true);
569 /// pkg.protect();
570 /// cache.resolve(true).unwrap();
571 ///
572 /// // This needs root
573 /// // cache.commit(&mut acquire_progress, &mut install_progress).unwrap();
574 /// ```
575 pub fn commit(
576 self,
577 progress: &mut AcquireProgress,
578 install_progress: &mut InstallProgress,
579 ) -> Result<(), AptErrors> {
580 // Lock the whole thing so as to prevent tamper
581 apt_lock()?;
582
583 let config = Config::new();
584 let archive_dir = config.dir("Dir::Cache::Archives", "/var/cache/apt/archives/");
585
586 // Copy local debs into archives dir
587 for deb in &self.local_debs {
588 // If file is already in the archive we don't copy
589 if deb.starts_with(archive_dir.as_str()) {
590 continue;
591 }
592 // If it reaches this point it really will be a valid filename, allegedly
593 if let Some(filename) = Path::new(deb).file_name() {
594 // Append the file name onto the archive dir
595 fs::copy(deb, archive_dir.to_string() + &filename.to_string_lossy())?;
596 }
597 }
598
599 // The archives can be grabbed during the apt lock.
600 self.get_archives(progress)?;
601
602 // If the system is locked we will want to unlock the dpkg files.
603 // This way when dpkg is running it can access its files.
604 apt_unlock_inner();
605
606 // Perform the operation.
607 self.do_install(install_progress)?;
608
609 // Finally Unlock the whole thing.
610 apt_unlock();
611 Ok(())
612 }
613
614 /// Get a single package.
615 ///
616 /// `cache.get("apt")` Returns a Package object for the native arch.
617 ///
618 /// `cache.get("apt:i386")` Returns a Package object for the i386 arch
619 pub fn get(&self, name: &str) -> Option<Package<'_>> {
620 Some(Package::new(self, unsafe {
621 self.find_pkg(name).make_safe()?
622 }))
623 }
624
625 /// An iterator over the packages
626 /// that will be altered when `cache.commit()` is called.
627 ///
628 /// # sort_name:
629 /// * [`true`] = Packages will be in alphabetical order
630 /// * [`false`] = Packages will not be sorted by name
631 pub fn get_changes(&self, sort_name: bool) -> impl Iterator<Item = Package<'_>> {
632 let mut changed = Vec::new();
633 let depcache = self.depcache();
634
635 for pkg in self.raw_pkgs() {
636 if depcache.marked_install(&pkg)
637 || depcache.marked_delete(&pkg)
638 || depcache.marked_upgrade(&pkg)
639 || depcache.marked_downgrade(&pkg)
640 || depcache.marked_reinstall(&pkg)
641 {
642 changed.push(pkg);
643 }
644 }
645
646 if sort_name {
647 // Sort by cached key seems to be the fastest for what we're doing.
648 // Maybe consider impl ord or something for these.
649 changed.sort_by_cached_key(|pkg| pkg.name().to_string());
650 }
651
652 changed
653 .into_iter()
654 .map(|pkg_ptr| Package::new(self, pkg_ptr))
655 }
656}
657
658/// Iterator Implementation for the Cache.
659pub struct CacheIter<'a> {
660 pkgs: IterPkgIterator,
661 cache: &'a Cache,
662}
663
664impl<'a> Iterator for CacheIter<'a> {
665 type Item = Package<'a>;
666
667 fn next(&mut self) -> Option<Self::Item> { Some(Package::new(self.cache, self.pkgs.next()?)) }
668}
669
670#[cxx::bridge]
671pub(crate) mod raw {
672 impl UniquePtr<PkgRecords> {}
673
674 unsafe extern "C++" {
675 include!("rust-apt/apt-pkg-c/cache.h");
676 type PkgCacheFile;
677
678 type PkgIterator = crate::raw::PkgIterator;
679 type VerIterator = crate::raw::VerIterator;
680 type PkgFileIterator = crate::raw::PkgFileIterator;
681 type PkgRecords = crate::records::raw::PkgRecords;
682 type SourceRecords = crate::records::raw::SourceRecords;
683 type IndexFile = crate::records::raw::IndexFile;
684 type PkgDepCache = crate::depcache::raw::PkgDepCache;
685 type AcqTextStatus = crate::acquire::raw::AcqTextStatus;
686 type PkgAcquire = crate::acquire::raw::PkgAcquire;
687
688 /// Create the CacheFile.
689 pub fn create_cache(volatile_files: &[&str]) -> Result<UniquePtr<PkgCacheFile>>;
690
691 /// Update the package lists, handle errors and return a Result.
692 pub fn update(self: &PkgCacheFile, progress: Pin<&mut AcqTextStatus>) -> Result<()>;
693
694 /// Loads the index files into PkgAcquire.
695 ///
696 /// Used to get to source list uris.
697 ///
698 /// It's not clear if this returning a bool is useful.
699 pub fn get_indexes(self: &PkgCacheFile, fetcher: &PkgAcquire) -> bool;
700
701 /// Return a pointer to PkgDepcache.
702 ///
703 /// # Safety
704 ///
705 /// The returned UniquePtr cannot outlive the cache.
706 unsafe fn create_depcache(self: &PkgCacheFile) -> UniquePtr<PkgDepCache>;
707
708 /// Return a pointer to PkgRecords.
709 ///
710 /// # Safety
711 ///
712 /// The returned UniquePtr cannot outlive the cache.
713 unsafe fn create_records(self: &PkgCacheFile) -> UniquePtr<PkgRecords>;
714
715 unsafe fn source_records(self: &PkgCacheFile) -> Result<UniquePtr<SourceRecords>>;
716
717 /// The priority of the Version as shown in `apt policy`.
718 pub fn priority(self: &PkgCacheFile, version: &VerIterator) -> i32;
719
720 /// Lookup the IndexFile of the Package file
721 ///
722 /// # Safety
723 ///
724 /// The IndexFile can not outlive PkgCacheFile.
725 ///
726 /// The returned UniquePtr cannot outlive the cache.
727 unsafe fn find_index(self: &PkgCacheFile, file: &PkgFileIterator) -> UniquePtr<IndexFile>;
728
729 /// Return a package by name and optionally architecture.
730 ///
731 /// # Safety
732 ///
733 /// If the Internal Pkg Pointer is NULL, operations can segfault.
734 /// You should call `make_safe()` asap to convert it to an Option.
735 ///
736 /// The returned UniquePtr cannot outlive the cache.
737 unsafe fn find_pkg(self: &PkgCacheFile, name: &str) -> UniquePtr<PkgIterator>;
738
739 /// Return the pointer to the start of the PkgIterator.
740 ///
741 /// # Safety
742 ///
743 /// If the Internal Pkg Pointer is NULL, operations can segfault.
744 /// You should call `raw_iter()` asap.
745 ///
746 /// The returned UniquePtr cannot outlive the cache.
747 unsafe fn begin(self: &PkgCacheFile) -> UniquePtr<PkgIterator>;
748 }
749}