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 NewInstall.
152 pub fn marked_new_install(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
153
154 /// Is the Package marked for install?
155 pub fn marked_install(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
156
157 /// Is the Package marked for upgrade?
158 pub fn marked_upgrade(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
159
160 /// Is the Package marked to be purged?
161 pub fn marked_purge(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
162
163 /// Is the Package marked for removal?
164 pub fn marked_delete(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
165
166 /// Is the Package held?
167 pub fn marked_held(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
168
169 /// Is the Package marked for keep?
170 pub fn marked_keep(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
171
172 /// Is the Package marked for downgrade?
173 pub fn marked_downgrade(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
174
175 /// Is the Package marked for reinstall?
176 pub fn marked_reinstall(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
177
178 /// # Mark a package as automatically installed.
179 ///
180 /// ## mark_auto:
181 /// * [true] = Mark the package as automatically installed.
182 /// * [false] = Mark the package as manually installed.
183 pub fn mark_auto(self: &PkgDepCache, pkg: &PkgIterator, mark_auto: bool);
184
185 /// # Mark a package for keep.
186 ///
187 /// ## Returns:
188 /// * [true] if the mark was successful
189 /// * [false] if the mark was unsuccessful
190 ///
191 /// This means that the package will not be changed from its current
192 /// version. This will not stop a reinstall, but will stop removal,
193 /// upgrades and downgrades
194 ///
195 /// We don't believe that there is any reason to unmark packages for
196 /// keep. If someone has a reason, and would like it implemented, please
197 /// put in a feature request.
198 pub fn mark_keep(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
199
200 /// # Mark a package for removal.
201 ///
202 /// ## Returns:
203 /// * [true] if the mark was successful
204 /// * [false] if the mark was unsuccessful
205 ///
206 /// ## purge:
207 /// * [true] = Configuration files will be removed along with the
208 /// package.
209 /// * [false] = Only the package will be removed.
210 pub fn mark_delete(self: &PkgDepCache, pkg: &PkgIterator, purge: bool) -> bool;
211
212 /// # Mark a package for installation.
213 ///
214 /// ## auto_inst:
215 /// * [true] = Additionally mark the dependencies for this package.
216 /// * [false] = Mark only this package.
217 ///
218 /// ## from_user:
219 /// * [true] = The package will be marked manually installed.
220 /// * [false] = The package will be unmarked automatically installed.
221 ///
222 /// ## Returns:
223 /// * [true] if the mark was successful
224 /// * [false] if the mark was unsuccessful
225 ///
226 /// If a package is already installed, at the latest version,
227 /// and you mark that package for install you will get true,
228 /// but the package will not be altered.
229 /// `pkg.marked_install()` will be false
230 pub fn mark_install(
231 self: &PkgDepCache,
232 pkg: &PkgIterator,
233 auto_inst: bool,
234 from_user: bool,
235 ) -> bool;
236
237 /// Set a version to be the candidate of it's package.
238 pub fn set_candidate_version(self: &PkgDepCache, ver: &VerIterator);
239
240 /// Get a pointer to the version that is set to be installed.
241 ///
242 /// # Safety
243 ///
244 /// If there is no candidate the inner pointer will be null.
245 /// This will cause segfaults if methods are used on a Null Version.
246 ///
247 /// Using [`crate::raw::IntoRawIter::make_safe`] to convert to an Option
248 /// is recommended.
249 ///
250 /// The returned UniquePtr cannot outlive the cache.
251 unsafe fn candidate_version(
252 self: &PkgDepCache,
253 pkg: &PkgIterator,
254 ) -> UniquePtr<VerIterator>;
255
256 /// Get a pointer to the version that is installed.
257 ///
258 /// # Safety
259 ///
260 /// If there is no version the inner pointer will be null.
261 /// This will cause segfaults if methods are used on a Null Version.
262 ///
263 /// Using [`crate::raw::IntoRawIter::make_safe`] to convert to an Option
264 /// is recommended.
265 ///
266 /// The returned UniquePtr cannot outlive the cache.
267 unsafe fn install_version(self: &PkgDepCache, pkg: &PkgIterator) -> UniquePtr<VerIterator>;
268
269 /// Returns the state of the dependency as u8
270 pub fn dep_state(self: &PkgDepCache, dep: &DepIterator) -> u8;
271
272 /// Checks if the dependency is important.
273 ///
274 /// Depends, PreDepends, Conflicts, Obsoletes, Breaks
275 /// will return [true].
276 ///
277 /// Suggests, Recommends will return [true] if they are
278 /// configured to be installed.
279 pub fn is_important_dep(self: &PkgDepCache, dep: &DepIterator) -> bool;
280
281 /// # Mark a package for reinstallation.
282 ///
283 /// ## Returns:
284 /// * [true] if the mark was successful
285 /// * [false] if the mark was unsuccessful
286 ///
287 /// ## reinstall:
288 /// * [true] = The package will be marked for reinstall.
289 /// * [false] = The package will be unmarked for reinstall.
290 pub fn mark_reinstall(self: &PkgDepCache, pkg: &PkgIterator, reinstall: bool);
291
292 /// Is the installed Package broken?
293 pub fn is_now_broken(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
294
295 /// Is the Package to be installed broken?
296 pub fn is_inst_broken(self: &PkgDepCache, pkg: &PkgIterator) -> bool;
297
298 /// The number of packages marked for installation.
299 pub fn install_count(self: &PkgDepCache) -> u32;
300
301 /// The number of packages marked for removal.
302 pub fn delete_count(self: &PkgDepCache) -> u32;
303
304 /// The number of packages marked for keep.
305 pub fn keep_count(self: &PkgDepCache) -> u32;
306
307 /// The number of packages with broken dependencies in the cache.
308 pub fn broken_count(self: &PkgDepCache) -> u32;
309
310 /// The size of all packages to be downloaded.
311 pub fn download_size(self: &PkgDepCache) -> u64;
312
313 /// The amount of space required for installing/removing the packages,"
314 ///
315 /// i.e. the Installed-Size of all packages marked for installation"
316 /// minus the Installed-Size of all packages for removal."
317 pub fn disk_size(self: &PkgDepCache) -> i64;
318 }
319}