1use crate::{Capability, CapabilityBound, Data, Dict, WeakInstanceToken};
6use async_trait::async_trait;
7use futures::future::BoxFuture;
8use router_error::RouterError;
9use std::fmt;
10use std::fmt::Debug;
11use std::sync::Arc;
12
13#[derive(Debug)]
15pub struct Request {
16 pub target: WeakInstanceToken,
18
19 pub metadata: Dict,
21}
22
23impl Request {
24 pub fn try_clone(&self) -> Result<Self, RouterError> {
28 self.metadata
29 .enumerate()
30 .find_map(|(_, v)| {
31 match v {
32 Ok(Capability::Dictionary(_)) => Some(Err::<Self, _>(RouterError::InvalidArgs)),
35 _ => None,
36 }
37 })
38 .transpose()?;
39 let metadata = self.metadata.shallow_copy().map_err(|()| RouterError::InvalidArgs)?;
40 Ok(Self { target: self.target.clone(), metadata })
41 }
42}
43
44#[async_trait]
47pub trait Routable<T>: Send + Sync
48where
49 T: CapabilityBound,
50{
51 async fn route(
52 &self,
53 request: Option<Request>,
54 debug: bool,
55 ) -> Result<RouterResponse<T>, RouterError>;
56}
57
58#[derive(Debug)]
60pub enum RouterResponse<T: CapabilityBound> {
61 Capability(T),
63
64 Unavailable,
66
67 Debug(Data),
69}
70
71impl<T: CapabilityBound> From<T> for RouterResponse<T> {
72 fn from(val: T) -> Self {
73 Self::Capability(val)
74 }
75}
76
77#[derive(Clone)]
89pub struct Router<T: CapabilityBound> {
90 routable: Arc<dyn Routable<T>>,
91}
92
93impl CapabilityBound for Router<crate::Connector> {
94 fn debug_typename() -> &'static str {
95 "ConnectorRouter"
96 }
97}
98impl CapabilityBound for Router<crate::Data> {
99 fn debug_typename() -> &'static str {
100 "DataRouter"
101 }
102}
103impl CapabilityBound for Router<crate::DirEntry> {
104 fn debug_typename() -> &'static str {
105 "DirEntryRouter"
106 }
107}
108impl CapabilityBound for Router<crate::Dict> {
109 fn debug_typename() -> &'static str {
110 "DictionaryRouter"
111 }
112}
113
114impl CapabilityBound for Router<crate::DirConnector> {
115 fn debug_typename() -> &'static str {
116 "DirConnectorRouter"
117 }
118}
119
120impl<T: CapabilityBound> fmt::Debug for Router<T> {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 f.debug_struct("Router").field("routable", &"[some routable object]").finish()
124 }
125}
126
127impl<T: CapabilityBound, F> Routable<T> for F
130where
131 F: Fn(Option<Request>, bool) -> BoxFuture<'static, Result<RouterResponse<T>, RouterError>>
132 + Send
133 + Sync
134 + 'static,
135{
136 fn route<'a, 'b>(
138 &'a self,
139 request: Option<Request>,
140 debug: bool,
141 ) -> BoxFuture<'b, Result<RouterResponse<T>, RouterError>>
142 where
143 'a: 'b,
144 Self: 'b,
145 {
146 self(request, debug)
147 }
148}
149
150#[async_trait]
151impl<T: CapabilityBound> Routable<T> for Router<T> {
152 async fn route(
153 &self,
154 request: Option<Request>,
155 debug: bool,
156 ) -> Result<RouterResponse<T>, RouterError> {
157 Router::route(self, request, debug).await
158 }
159}
160
161impl<T: CapabilityBound> Router<T> {
162 pub fn new(routable: impl Routable<T> + 'static) -> Self {
164 Self { routable: Arc::new(routable) }
165 }
166
167 pub fn new_error(error: impl Into<RouterError>) -> Self {
169 let v: RouterError = error.into();
170 Self::new(ErrRouter { v })
171 }
172
173 pub fn new_debug(data: impl Into<Data>) -> Self {
175 let v: Data = data.into();
176 Self::new(DebugRouter { v })
177 }
178
179 pub async fn route(
181 &self,
182 request: Option<Request>,
183 debug: bool,
184 ) -> Result<RouterResponse<T>, RouterError> {
185 self.routable.route(request, debug).await
186 }
187}
188
189impl<T: Clone + CapabilityBound> Router<T> {
190 pub fn new_ok(c: impl Into<T>) -> Self {
193 let v: T = c.into();
194 Self::new(OkRouter { v })
195 }
196}
197
198#[derive(Clone)]
199struct OkRouter<T: Clone + CapabilityBound> {
200 v: T,
201}
202
203#[async_trait]
204impl<T: Clone + CapabilityBound> Routable<T> for OkRouter<T> {
205 async fn route(
206 &self,
207 _request: Option<Request>,
208 _debug: bool,
209 ) -> Result<RouterResponse<T>, RouterError> {
210 Ok(RouterResponse::Capability(self.v.clone()))
211 }
212}
213
214#[derive(Clone)]
215struct DebugRouter {
216 v: Data,
217}
218
219#[async_trait]
220impl<T: CapabilityBound> Routable<T> for DebugRouter {
221 async fn route(
222 &self,
223 _request: Option<Request>,
224 _debug: bool,
225 ) -> Result<RouterResponse<T>, RouterError> {
226 Ok(RouterResponse::Debug(self.v.clone()))
227 }
228}
229
230#[derive(Clone)]
231struct ErrRouter {
232 v: RouterError,
233}
234
235#[async_trait]
236impl<T: CapabilityBound> Routable<T> for ErrRouter {
237 async fn route(
238 &self,
239 _request: Option<Request>,
240 _debug: bool,
241 ) -> Result<RouterResponse<T>, RouterError> {
242 Err(self.v.clone())
243 }
244}