dope_core/driver/lifecycle/finalize.rs
1use crate::driver::lifecycle::{quiesce, routing};
2
3/// Post-quiescence access to driver resource finalization.
4///
5/// File-table mutation is deliberately absent: descriptors remain affine
6/// fields of their owner and are reclaimed only after that owner is dropped.
7///
8/// ```compile_fail,E0599
9/// use dope_core::driver::lifecycle::Finalize;
10///
11/// fn cannot_reopen_file_authority(finish: &mut Finalize<'_, '_>) {
12/// let _ = finish.files();
13/// }
14/// ```
15#[must_use]
16#[repr(transparent)]
17pub struct Finalize<'a, 'd> {
18 finalization: quiesce::Final<'a, 'd>,
19}
20
21impl<'a, 'd> Finalize<'a, 'd> {
22 #[doc(hidden)]
23 pub fn new(finalization: quiesce::Final<'a, 'd>) -> Self {
24 Self { finalization }
25 }
26
27 #[doc(hidden)]
28 pub fn reborrow(&mut self) -> Finalize<'_, 'd> {
29 Finalize {
30 finalization: self.finalization.reborrow(),
31 }
32 }
33
34 pub fn retire_route<const ID: u8>(&mut self, route: &routing::Route<'d, ID>) {
35 route.finish(self.finalization.context());
36 }
37
38 /// Stages a quiesced storage route for a later application installation.
39 ///
40 /// ```compile_fail
41 /// use dope_core::driver::lifecycle::{Finalize, routing::Route};
42 ///
43 /// fn stage_application<'a, 'd>(
44 /// finish: &mut Finalize<'a, 'd>,
45 /// route: &Route<'d, 7>,
46 /// ) {
47 /// finish.stage_route(route);
48 /// }
49 /// ```
50 ///
51 /// ```compile_fail
52 /// use dope_core::driver::lifecycle::{Finalize, routing::StorageRoute};
53 ///
54 /// fn retire_storage<'a, 'd>(
55 /// finish: &mut Finalize<'a, 'd>,
56 /// route: &StorageRoute<'d, 7>,
57 /// ) {
58 /// finish.retire_route(route);
59 /// }
60 /// ```
61 pub fn stage_route<const ID: u8>(&mut self, route: &routing::StorageRoute<'d, ID>) {
62 route.stage();
63 }
64}
65
66const _: () = assert!(
67 std::mem::size_of::<Finalize<'static, 'static>>()
68 == std::mem::size_of::<quiesce::Final<'static, 'static>>()
69);