dope_core/driver/storage/
mod.rs1use std::{convert, error, fmt, io};
2
3use o3::cell::region;
4
5use crate::driver::{self, flight, lifecycle::routing, route, schedule::timer};
6
7mod impossible;
8mod never;
9pub(super) mod ownership;
10pub(super) mod retirements;
11
12pub(super) use impossible::Impossible;
13pub use never::Never;
14
15pub struct Context<'a, 'd> {
36 context: driver::Context<'a, 'd>,
37}
38
39impl<'a, 'd> Context<'a, 'd> {
40 pub(super) fn new(context: driver::Context<'a, 'd>) -> Self {
41 Self { context }
42 }
43
44 pub fn driver(&self) -> driver::Reference<'d> {
45 self.context.driver_ref()
46 }
47
48 pub fn region(&self) -> ®ion::Token<'d> {
49 self.context.region_token_ref()
50 }
51
52 pub fn timer(&self) -> &'d timer::Timer<'d> {
53 self.context.timer()
54 }
55
56 #[doc(hidden)]
57 pub fn flight_slots<Tag: route::Tag>(
58 &mut self,
59 capacity: usize,
60 ) -> io::Result<flight::Slots<'d, Tag>> {
61 self.context.flight_slots(capacity)
62 }
63
64 pub fn reserve_route<const ID: u8>(&mut self) -> io::Result<routing::Reserved<'d, ID>> {
65 use crate::driver::route::FRAMEWORK;
66
67 if ID == FRAMEWORK {
68 return Err(io::Error::new(
69 io::ErrorKind::InvalidInput,
70 "dope: reserved route",
71 ));
72 }
73 routing::Reserved::reserve_allowed(&mut self.context)
74 }
75}
76
77pub trait Factory: 'static {
79 type Output<'d>: 'd;
80 type Error: error::Error + Send + Sync + 'static;
81
82 fn build<'d>(self, context: &mut Context<'_, 'd>) -> Result<Self::Output<'d>, Self::Error>;
83}
84
85pub struct Value<T>(T);
86
87impl<T> Value<T> {
88 pub const fn new(value: T) -> Self {
89 Self(value)
90 }
91}
92
93impl<T: 'static> Factory for Value<T> {
94 type Output<'d> = T;
95 type Error = convert::Infallible;
96
97 fn build<'d>(self, _context: &mut Context<'_, 'd>) -> Result<Self::Output<'d>, Self::Error> {
98 Ok(self.0)
99 }
100}
101
102impl Factory for () {
103 type Output<'d> = ();
104 type Error = convert::Infallible;
105
106 fn build<'d>(self, _context: &mut Context<'_, 'd>) -> Result<Self::Output<'d>, Self::Error> {
107 Ok(())
108 }
109}
110
111impl<F: Factory> Factory for Option<F> {
112 type Output<'d> = Option<F::Output<'d>>;
113 type Error = F::Error;
114
115 fn build<'d>(self, context: &mut Context<'_, 'd>) -> Result<Self::Output<'d>, Self::Error> {
116 self.map(|factory| factory.build(context)).transpose()
117 }
118}
119
120#[derive(Debug)]
121pub enum PairError<A, B> {
122 First(A),
123 Second(B),
124}
125
126impl<A: fmt::Display, B: fmt::Display> fmt::Display for PairError<A, B> {
127 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
128 match self {
129 Self::First(error) => error.fmt(formatter),
130 Self::Second(error) => error.fmt(formatter),
131 }
132 }
133}
134
135impl<A, B> error::Error for PairError<A, B>
136where
137 A: error::Error + 'static,
138 B: error::Error + 'static,
139{
140}
141
142impl<A: Factory, B: Factory> Factory for (A, B) {
143 type Output<'d> = (A::Output<'d>, B::Output<'d>);
144 type Error = PairError<A::Error, B::Error>;
145
146 fn build<'d>(self, context: &mut Context<'_, 'd>) -> Result<Self::Output<'d>, Self::Error> {
147 let first = Factory::build(self.0, context).map_err(PairError::First)?;
148 let second = Factory::build(self.1, context).map_err(PairError::Second)?;
149 Ok((first, second))
150 }
151}