Skip to main content

dope_runtime/executor/raw/
released.rs

1use std::{mem, pin};
2
3use crate::executor;
4
5/// Ended external client access to one exact pinned application.
6#[must_use]
7#[repr(transparent)]
8pub struct Released<'app, R> {
9    app: pin::Pin<&'app mut R>,
10}
11
12impl<'app, R> Released<'app, R> {
13    pub(crate) const fn new(app: pin::Pin<&'app mut R>) -> Self {
14        Self { app }
15    }
16
17    pub fn owner(&mut self) -> pin::Pin<&mut R> {
18        self.app.as_mut()
19    }
20
21    /// # Safety
22    /// Project an unchanged pinned owned field of this exact root, with no remaining external clients.
23    pub unsafe fn visit<'d, T: executor::raw::App<'d>>(
24        mut self,
25        project: impl for<'a> FnOnce(pin::Pin<&'a mut R>) -> pin::Pin<&'a mut T>,
26    ) -> Self {
27        let app = project(self.app.as_mut());
28        let _ = T::released(Released::new(app));
29        self
30    }
31
32    /// # Safety
33    /// Project the unchanged optional pinned owned field of this exact root, with no remaining external clients.
34    pub unsafe fn optional<'d, T: executor::raw::App<'d>>(
35        mut self,
36        project: impl for<'a> FnOnce(pin::Pin<&'a mut R>) -> Option<pin::Pin<&'a mut T>>,
37    ) -> Self {
38        if let Some(app) = project(self.app.as_mut()) {
39            let _ = T::released(Released::new(app));
40        }
41        self
42    }
43}
44
45const _: () = assert!(mem::size_of::<Released<'_, ()>>() == mem::size_of::<usize>());