rust_apt/
depcache.rs

1//! Dependency Extension data for the cache.
2//!
3//! The following was taken from libapt-pkg documentation.
4//!
5//! This class stores the cache data and a set of extension structures for
6//! monitoring the current state of all the packages. It also generates and
7//! caches the 'install' state of many things. This refers to the state of the
8//! package after an install has been run.
9//!
10//! The StateCache::State field can be -1,0,1,2 which is <,=,>,no current.
11//! StateCache::Mode is which of the 3 fields is active.
12//!
13//! This structure is important to support the readonly status of the cache
14//! file. When the data is saved the cache will be refreshed from our
15//! internal rep and written to disk. Then the actual persistent data
16//! files will be put on the disk.
17//!
18//! Each dependency is compared against 3 target versions to produce to
19//! 3 dependency results.
20//!   Now - Compared using the Currently install version
21//!   Install - Compared using the install version (final state)
22//!   CVer - (Candidate Version) Compared using the Candidate Version
23//! The candidate and now results are used to decide whether a package
24//! should be automatically installed or if it should be left alone.
25//!
26//! Remember, the Candidate Version is selected based on the distribution
27//! settings for the Package. The Install Version is selected based on the
28//! state (Delete, Keep, Install) field and can be either the Current Version
29//! or the Candidate version.
30//!
31//! The Candidate version is what is shown the 'Install Version' field.
32
33use cxx::UniquePtr;
34
35use crate::error::AptErrors;
36use crate::progress::OperationProgress;
37use crate::raw::PkgDepCache;
38use crate::util::DiskSpace;
39
40/// Dependency Extension data for the cache.
41pub struct DepCache {
42	pub(crate) ptr: UniquePtr<PkgDepCache>,
43}
44
45impl DepCache {
46	pub fn new(ptr: UniquePtr<PkgDepCache>) -> DepCache { DepCache { ptr } }
47
48	/// Clear any marked changes in the DepCache.
49	pub fn clear_marked(&self) -> Result<(), AptErrors> {
50		Ok(self.init(OperationProgress::quiet().pin().as_mut())?)
51	}
52
53	/// The amount of space required for installing/removing the packages."
54	///
55	/// i.e. the Installed-Size of all packages marked for installation"
56	/// minus the Installed-Size of all packages for removal."
57	pub fn disk_size(&self) -> DiskSpace {
58		let size = self.ptr.disk_size();
59		if size < 0 {
60			return DiskSpace::Free(-size as u64);
61		}
62		DiskSpace::Require(size as u64)
63	}
64}
65
66#[cxx::bridge]
67pub(crate) mod raw {
68	impl UniquePtr<PkgDepCache> {}
69	unsafe extern "C++" {
70		include!("rust-apt/apt-pkg-c/depcache.h");
71
72		type PkgDepCache;
73		/// An action group is a group of actions that are currently being
74		/// performed.
75		///
76		/// While an active group is active, certain routine
77		/// clean-up actions that would normally be performed after every
78		/// cache operation are delayed until the action group is
79		/// completed. This is necessary primarily to avoid inefficiencies
80		/// when modifying a large number of packages at once.
81		///
82		/// This struct represents an active action group. Creating an
83		/// instance will create an action group; destroying one will
84		/// destroy the corresponding action group.
85		///
86		/// The following operations are suppressed by this class:
87		///
88		///   - Keeping the Marked and Garbage flags up to date.
89		///
90		/// Here is an example of creating and releasing an ActionGroup.
91		///
92		/// ```
93		/// use rust_apt::new_cache;
94		///
95		/// let cache = new_cache!().unwrap();
96		/// let mut action_group = unsafe { cache.depcache().action_group() };
97		///
98		/// // The C++ deconstructor will be run when the action group leaves scope.
99		/// // You can also call it explicitly.
100		/// action_group.pin_mut().release();
101		/// ```
102		type ActionGroup;
103		type PkgIterator = crate::iterators::PkgIterator;
104		type VerIterator = crate::iterators::VerIterator;
105		type DepIterator = crate::iterators::DepIterator;
106		type OperationProgress<'a> = crate::progress::OperationProgress<'a>;
107
108		/// Clear any marked changes in the DepCache.
109		pub fn init(self: &PkgDepCache, callback: Pin<&mut OperationProgress>) -> Result<()>;
110
111		/// Autoinstall every broken package and run the problem resolver
112		/// Returns false if the problem resolver fails.
113		pub fn fix_broken(self: &PkgDepCache) -> bool;
114		/// Return a new [`ActionGroup`] of the current DepCache
115		///
116		/// ActionGroup will be released once it leaves scope
117		/// or ['ActionGroup::release'] is called
118		///
119		/// # Safety
120		///
121		/// The returned UniquePtr cannot outlive the cache.
122		unsafe fn action_group(self: &PkgDepCache) -> UniquePtr<ActionGroup>;
123
124		/// This will release the [`ActionGroup`] which will trigger a
125		/// MarkAndSweep
126		pub fn release(self: Pin<&mut ActionGroup>);
127
128		/// Perform an Upgrade.
129		///
130		/// ## mark_auto:
131		///   * [0] = Remove and install new packages if necessary.
132		///   * [1] = New packages will be installed but nothing will be
133		///     removed.
134		///   * [3] = Neither remove or install new packages.
135		pub fn upgrade(
136			self: &PkgDepCache,
137			progress: Pin<&mut OperationProgress>,
138			upgrade_mode: i32,
139		) -> Result<()>;
140
141		/// Check if the package is upgradable.
142		pub fn is_upgradable(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
143
144		/// Is the Package auto installed? Packages marked as auto installed are
145		/// usually dependencies.
146		pub fn is_auto_installed(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
147
148		/// Is the Package able to be auto removed?
149		pub fn is_garbage(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
150
151		/// Is the Package marked for install?
152		pub fn marked_install(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
153
154		/// Is the Package marked for upgrade?
155		pub fn marked_upgrade(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
156
157		/// Is the Package marked to be purged?
158		pub fn marked_purge(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
159
160		/// Is the Package marked for removal?
161		pub fn marked_delete(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
162
163		/// Is the Package marked for keep?
164		pub fn marked_keep(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
165
166		/// Is the Package marked for downgrade?
167		pub fn marked_downgrade(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
168
169		/// Is the Package marked for reinstall?
170		pub fn marked_reinstall(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
171
172		/// # Mark a package as automatically installed.
173		///
174		/// ## mark_auto:
175		///   * [true] = Mark the package as automatically installed.
176		///   * [false] = Mark the package as manually installed.
177		pub fn mark_auto(self: &PkgDepCache, pkg: &PkgIterator, mark_auto: bool);
178
179		/// # Mark a package for keep.
180		///
181		/// ## Returns:
182		///   * [true] if the mark was successful
183		///   * [false] if the mark was unsuccessful
184		///
185		/// This means that the package will not be changed from its current
186		/// version. This will not stop a reinstall, but will stop removal,
187		/// upgrades and downgrades
188		///
189		/// We don't believe that there is any reason to unmark packages for
190		/// keep. If someone has a reason, and would like it implemented, please
191		/// put in a feature request.
192		pub fn mark_keep(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
193
194		/// # Mark a package for removal.
195		///
196		/// ## Returns:
197		///   * [true] if the mark was successful
198		///   * [false] if the mark was unsuccessful
199		///
200		/// ## purge:
201		///   * [true] = Configuration files will be removed along with the
202		///     package.
203		///   * [false] = Only the package will be removed.
204		pub fn mark_delete(self: &PkgDepCache, pkg: &PkgIterator, purge: bool) -> bool;
205
206		/// # Mark a package for installation.
207		///
208		/// ## auto_inst:
209		///   * [true] = Additionally mark the dependencies for this package.
210		///   * [false] = Mark only this package.
211		///
212		/// ## from_user:
213		///   * [true] = The package will be marked manually installed.
214		///   * [false] = The package will be unmarked automatically installed.
215		///
216		/// ## Returns:
217		///   * [true] if the mark was successful
218		///   * [false] if the mark was unsuccessful
219		///
220		/// If a package is already installed, at the latest version,
221		/// and you mark that package for install you will get true,
222		/// but the package will not be altered.
223		/// `pkg.marked_install()` will be false
224		pub fn mark_install(
225			self: &PkgDepCache,
226			pkg: &PkgIterator,
227			auto_inst: bool,
228			from_user: bool,
229		) -> bool;
230
231		/// Set a version to be the candidate of it's package.
232		pub fn set_candidate_version(self: &PkgDepCache, ver: &VerIterator);
233
234		/// Get a pointer to the version that is set to be installed.
235		///
236		/// # Safety
237		///
238		/// If there is no candidate the inner pointer will be null.
239		/// This will cause segfaults if methods are used on a Null Version.
240		///
241		/// Using [`crate::raw::IntoRawIter::make_safe`] to convert to an Option
242		/// is recommended.
243		///
244		/// The returned UniquePtr cannot outlive the cache.
245		unsafe fn candidate_version(
246			self: &PkgDepCache,
247			pkg: &PkgIterator,
248		) -> UniquePtr<VerIterator>;
249
250		/// Get a pointer to the version that is installed.
251		///
252		/// # Safety
253		///
254		/// If there is no version the inner pointer will be null.
255		/// This will cause segfaults if methods are used on a Null Version.
256		///
257		/// Using [`crate::raw::IntoRawIter::make_safe`] to convert to an Option
258		/// is recommended.
259		///
260		/// The returned UniquePtr cannot outlive the cache.
261		unsafe fn install_version(self: &PkgDepCache, pkg: &PkgIterator) -> UniquePtr<VerIterator>;
262
263		/// Returns the state of the dependency as u8
264		pub fn dep_state(self: &PkgDepCache, dep: &DepIterator) -> u8;
265
266		/// Checks if the dependency is important.
267		///
268		/// Depends, PreDepends, Conflicts, Obsoletes, Breaks
269		/// will return [true].
270		///
271		/// Suggests, Recommends will return [true] if they are
272		/// configured to be installed.
273		pub fn is_important_dep(self: &PkgDepCache, dep: &DepIterator) -> bool;
274
275		/// # Mark a package for reinstallation.
276		///
277		/// ## Returns:
278		///   * [true] if the mark was successful
279		///   * [false] if the mark was unsuccessful
280		///
281		/// ## reinstall:
282		///   * [true] = The package will be marked for reinstall.
283		///   * [false] = The package will be unmarked for reinstall.
284		pub fn mark_reinstall(self: &PkgDepCache, pkg: &PkgIterator, reinstall: bool);
285
286		/// Is the installed Package broken?
287		pub fn is_now_broken(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
288
289		/// Is the Package to be installed broken?
290		pub fn is_inst_broken(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
291
292		/// The number of packages marked for installation.
293		pub fn install_count(self: &PkgDepCache) -> u32;
294
295		/// The number of packages marked for removal.
296		pub fn delete_count(self: &PkgDepCache) -> u32;
297
298		/// The number of packages marked for keep.
299		pub fn keep_count(self: &PkgDepCache) -> u32;
300
301		/// The number of packages with broken dependencies in the cache.
302		pub fn broken_count(self: &PkgDepCache) -> u32;
303
304		/// The size of all packages to be downloaded.
305		pub fn download_size(self: &PkgDepCache) -> u64;
306
307		/// The amount of space required for installing/removing the packages,"
308		///
309		/// i.e. the Installed-Size of all packages marked for installation"
310		/// minus the Installed-Size of all packages for removal."
311		pub fn disk_size(self: &PkgDepCache) -> i64;
312	}
313}