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(super) 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{
24 pub fn drive<R>(&mut self, root: R) -> Result<R::Output, drive::Error>
25 where
26 R: root::Root<'d>,
27 {
28 self.access
29 .reborrow()
30 .drive(clock::wall(), root, drive::tick)
31 }
32
33 pub fn run(self) -> Result<shutdown::Requested<Q>, drive::Error> {
34 self.access.run()?;
35 Ok(shutdown::Requested::new())
36 }
37
38 pub fn drive_until<R>(
41 self,
42 root: R,
43 ) -> Result<ops::ControlFlow<R::Output, shutdown::Requested<Q>>, drive::Error>
44 where
45 R: root::Root<'d>,
46 {
47 Ok(self
48 .access
49 .drive_until(root)?
50 .map_continue(|()| shutdown::Requested::new()))
51 }
52
53 pub fn drive_for<R>(
56 &mut self,
57 timeout: time::Duration,
58 root: R,
59 ) -> Result<R::Output, drive::Error>
60 where
61 R: root::Root<'d>,
62 {
63 let source = clock::Bound::until(clock::wall(), timeout)?;
64 self.access.reborrow().drive(source, root, drive::timeout)
65 }
66
67 pub fn run_for(self, timeout: time::Duration) -> Result<shutdown::Requested<Q>, drive::Error> {
70 self.access.run_for(timeout)?;
71 Ok(shutdown::Requested::new())
72 }
73
74 pub fn run_drain(self, timeout: Positive) -> Result<drain::Report<Q>, drive::Error>
75 where
76 D: executor::raw::Drain<'d>,
77 {
78 let outcome = self.access.run_drain(timeout)?;
79 Ok(drain::Report::new(shutdown::Requested::new(), outcome))
80 }
81
82 pub fn drive_drain<R>(
85 self,
86 timeout: Positive,
87 root: R,
88 ) -> Result<ops::ControlFlow<R::Output, drain::Report<Q>>, drive::Error>
89 where
90 D: executor::raw::Drain<'d>,
91 R: root::Root<'d>,
92 {
93 Ok(self
94 .access
95 .drive_drain(timeout, root)?
96 .map_continue(|outcome| drain::Report::new(shutdown::Requested::new(), outcome)))
97 }
98}
99
100impl<'app, 'life: 'app, 'd: 'life, D, Q> ops::Deref for App<'app, 'life, 'd, D, Q>
101where
102 D: executor::raw::Layout<'d>,
103{
104 type Target = session::access::Access<'app, 'life, 'd, D, Q>;
105
106 fn deref(&self) -> &Self::Target {
107 &self.access
108 }
109}
110
111impl<'d, D: executor::raw::Layout<'d>, Q> ops::DerefMut for App<'_, '_, 'd, D, Q> {
112 fn deref_mut(&mut self) -> &mut Self::Target {
113 &mut self.access
114 }
115}