routing/bedrock/
use_dictionary_router.rs1use crate::capability_source::CapabilitySource;
6use crate::error::RoutingError;
7use async_trait::async_trait;
8use futures::StreamExt;
9use futures::stream::FuturesUnordered;
10use router_error::RouterError;
11use sandbox::{Dict, Request, Routable, Router, RouterResponse};
12
13pub struct UseDictionaryRouter {
17 original_dictionary: Dict,
18 dictionary_routers: Vec<Router<Dict>>,
19 capability_source: CapabilitySource,
20}
21
22impl UseDictionaryRouter {
23 pub fn new(
24 original_dictionary: Dict,
25 dictionary_routers: Vec<Router<Dict>>,
26 capability_source: CapabilitySource,
27 ) -> Router<Dict> {
28 Router::new(Self { original_dictionary, dictionary_routers, capability_source })
29 }
30}
31
32#[async_trait]
33impl Routable<Dict> for UseDictionaryRouter {
34 async fn route(
35 &self,
36 request: Option<Request>,
37 debug: bool,
38 ) -> Result<RouterResponse<Dict>, RouterError> {
39 if debug {
40 return Ok(RouterResponse::Debug(
41 self.capability_source
42 .clone()
43 .try_into()
44 .expect("failed to serialize capability source"),
45 ));
46 }
47 let mut futures_unordered = FuturesUnordered::new();
48 for dictionary_router in self.dictionary_routers.iter() {
49 let request = request.as_ref().and_then(|r| r.try_clone().ok());
50 futures_unordered.push(dictionary_router.route(request, false));
51 }
52 let resulting_dictionary = self.original_dictionary.shallow_copy().unwrap();
53 while let Some(route_result) = futures_unordered.next().await {
54 match route_result {
55 Ok(RouterResponse::Capability(other_dictionary)) => {
56 let maybe_conflicting_name =
57 resulting_dictionary.follow_updates_from(other_dictionary).await;
58 if let Some(conflicting_name) = maybe_conflicting_name {
59 return Err(RoutingError::ConflictingDictionaryEntries {
60 moniker: self.capability_source.source_moniker(),
61 conflicting_name,
62 }
63 .into());
64 }
65 }
66 Ok(RouterResponse::Unavailable) => (),
67 Ok(RouterResponse::Debug(_)) => {
68 panic!("got debug response when we didn't request one")
69 }
70 Err(_e) => {
71 }
76 }
77 }
78 Ok(resulting_dictionary.into())
79 }
80}