dope_runtime/executor/session/
app.rs1use std::{ops, time};
2
3use o3::base::time::Positive;
4
5use crate::{
6 executor::{
7 self, drain,
8 drive::{self, clock},
9 root, session,
10 },
11 shutdown,
12};
13
14#[repr(transparent)]
16pub struct App<'app, 'life: 'app, 'd: 'life, D: executor::raw::Layout<'d>, Q = ()> {
17 pub(crate) access: session::access::Access<'app, 'life, 'd, D, Q>,
18}
19
20impl<'app, 'life: 'app, 'd: 'life, D, Q> App<'app, 'life, 'd, D, Q>
21where
22 D: executor::raw::App<'d>,
23 Q: executor::Startup,
24{
25 pub fn drive<R>(&mut self, root: R) -> Result<R::Output, drive::Error>
26 where
27 R: root::Root<'d>,
28 {
29 self.access
30 .reborrow()
31 .drive(clock::wall(), root, drive::tick)
32 }
33
34 pub fn run(self) -> Result<shutdown::Requested<Q>, drive::Error> {
35 self.access.run()?;
36 Ok(shutdown::Requested::new())
37 }
38
39 pub fn drive_until<R>(
42 self,
43 root: R,
44 ) -> Result<ops::ControlFlow<R::Output, shutdown::Requested<Q>>, drive::Error>
45 where
46 R: root::Root<'d>,
47 {
48 Ok(self
49 .access
50 .drive_until(root)?
51 .map_continue(|()| shutdown::Requested::new()))
52 }
53
54 pub fn drive_for<R>(
57 &mut self,
58 timeout: time::Duration,
59 root: R,
60 ) -> Result<R::Output, drive::Error>
61 where
62 R: root::Root<'d>,
63 {
64 let source = clock::Bound::until(clock::wall(), timeout)?;
65 self.access.reborrow().drive(source, root, drive::timeout)
66 }
67
68 pub fn run_for(self, timeout: time::Duration) -> Result<shutdown::Requested<Q>, drive::Error> {
71 self.access.run_for(timeout)?;
72 Ok(shutdown::Requested::new())
73 }
74
75 pub fn run_drain(self, timeout: Positive) -> Result<drain::Report<Q>, drive::Error>
76 where
77 D: executor::raw::Drain<'d>,
78 {
79 let outcome = self.access.run_drain(timeout)?;
80 Ok(drain::Report::new(shutdown::Requested::new(), outcome))
81 }
82
83 pub fn drive_drain<R>(
86 self,
87 timeout: Positive,
88 root: R,
89 ) -> Result<ops::ControlFlow<R::Output, drain::Report<Q>>, drive::Error>
90 where
91 D: executor::raw::Drain<'d>,
92 R: root::Root<'d>,
93 {
94 Ok(self
95 .access
96 .drive_drain(timeout, root)?
97 .map_continue(|outcome| drain::Report::new(shutdown::Requested::new(), outcome)))
98 }
99}
100
101impl<'app, 'life: 'app, 'd: 'life, D, Q> ops::Deref for App<'app, 'life, 'd, D, Q>
102where
103 D: executor::raw::Layout<'d>,
104{
105 type Target = session::access::Access<'app, 'life, 'd, D, Q>;
106
107 fn deref(&self) -> &Self::Target {
108 &self.access
109 }
110}
111
112impl<'d, D: executor::raw::Layout<'d>, Q> ops::DerefMut for App<'_, '_, 'd, D, Q> {
113 fn deref_mut(&mut self) -> &mut Self::Target {
114 &mut self.access
115 }
116}