1use dope_core::driver::storage;
2
3use crate::{
4 executor::{self, boot, session},
5 topology::{self, app, lending},
6};
7
8pub struct Worker<'scope, 'life: 'scope, 'p: 'life, 'd: 'p, S: storage::Plan + 'd, I: 'd, Q: 'd> {
10 pub(super) session: session::Scope<'scope, 'life, 'p, 'd, S, Q>,
11 pub(super) installer: I,
12}
13
14impl<'scope, 'life: 'scope, 'p: 'life, 'd: 'p, S: storage::Plan + 'd, I: 'd, Q: 'd>
15 Worker<'scope, 'life, 'p, 'd, S, I, Q>
16{
17 pub(crate) const fn new(
18 session: session::Scope<'scope, 'life, 'p, 'd, S, Q>,
19 setup: I,
20 ) -> Self {
21 Self {
22 session,
23 installer: setup,
24 }
25 }
26}
27
28impl<'scope, 'life: 'scope, 'p: 'life, 'd: 'p, S, I, Q> Worker<'scope, 'life, 'p, 'd, S, I, Q>
29where
30 S: storage::Plan + 'd,
31 I: 'd,
32 Q: executor::Startup + 'd,
33{
34 pub fn storage(&self) -> &'life S::Output<'p, 'd> {
36 self.session.storage()
37 }
38
39 pub fn lend<R>(
41 mut self,
42 compose: impl FnOnce(I, &mut lending::Stage<'_, 'scope, 'life, 'p, 'd, S, Q>) -> R,
43 ) -> R {
44 let mut stage = lending::Stage::new(&mut self.session);
45 compose(self.installer, &mut stage)
46 }
47
48 pub fn with<N, R, E>(mut self, next: N) -> Result<R, E>
50 where
51 I: for<'stage> lending::Installer<
52 lending::Stage<'stage, 'scope, 'life, 'p, 'd, S, Q>,
53 N,
54 Output = R,
55 Error = E,
56 >,
57 {
58 let mut stage = lending::Stage::new(&mut self.session);
59 self.installer.install(&mut stage, next)
60 }
61
62 pub fn install_with<A, R, E>(
65 mut self,
66 install: impl FnOnce(I, &topology::Boot<'_, 'scope, 'life, 'p, 'd, S, Q>) -> R,
67 ) -> Result<app::Application<'scope, 'life, 'p, 'd, S, A, Q>, topology::InstallError<E>>
68 where
69 A: executor::raw::App<'d>,
70 R: boot::Root<'d, Output = Result<A, E>>,
71 {
72 let root = {
73 let stage = topology::Boot::new(&self.session);
74 install(self.installer, &stage)
75 };
76 let app = self
77 .session
78 .drive(root)
79 .map_err(topology::InstallError::Drive)?
80 .map_err(topology::InstallError::Install)?;
81 Ok(app::Application {
82 session: self.session,
83 app,
84 })
85 }
86}
87
88impl<'scope, 'life: 'scope, 'p: 'life, 'd: 'p, S, I, Q> Worker<'scope, 'life, 'p, 'd, S, I, Q>
89where
90 S: storage::Plan + 'd,
91 I: topology::Installer<S> + 'd,
92 Q: executor::Startup + 'd,
93{
94 pub fn install(
95 mut self,
96 ) -> Result<app::Application<'scope, 'life, 'p, 'd, S, I::App<'life, 'p, 'd>, Q>, I::Error>
97 {
98 let app = {
99 let mut stage = topology::Stage::new(&mut self.session);
100 self.installer.install(&mut stage)?
101 };
102 Ok(app::Application {
103 session: self.session,
104 app,
105 })
106 }
107}