stellation_bridge/registry/
routine.rs1use std::any::TypeId;
2use std::fmt;
3use std::rc::Rc;
4use std::sync::Arc;
5
6use super::Incoming;
7use crate::routines::{BridgedMutation, BridgedQuery, MutationResult, QueryResult};
8use crate::{BridgeError, BridgeResult};
9
10#[derive(Default)]
12pub struct RoutineRegistryBuilder {
13 query_ids: Vec<TypeId>,
14}
15
16impl fmt::Debug for RoutineRegistryBuilder {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 f.debug_struct("RoutineRegistryBuilder")
19 .finish_non_exhaustive()
20 }
21}
22
23impl RoutineRegistryBuilder {
24 pub fn new() -> Self {
26 Self::default()
27 }
28
29 pub fn build(self) -> RoutineRegistry {
31 RoutineRegistry {
32 inner: Arc::new(self),
33 }
34 }
35
36 pub fn add_mutation<T>(mut self) -> Self
38 where
39 T: 'static + BridgedMutation,
40 {
41 let type_id = TypeId::of::<T>();
42 self.query_ids.push(type_id);
43
44 self
45 }
46
47 pub fn add_query<T>(mut self) -> Self
49 where
50 T: 'static + BridgedQuery,
51 {
52 let type_id = TypeId::of::<T>();
53 self.query_ids.push(type_id);
54
55 self
56 }
57}
58
59pub struct RoutineRegistry {
61 inner: Arc<RoutineRegistryBuilder>,
62}
63
64impl fmt::Debug for RoutineRegistry {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 f.debug_struct("RoutineRegistry").finish_non_exhaustive()
67 }
68}
69
70impl PartialEq for RoutineRegistry {
71 fn eq(&self, other: &Self) -> bool {
72 Arc::ptr_eq(&self.inner, &other.inner)
73 }
74}
75
76impl Eq for RoutineRegistry {}
77
78impl Clone for RoutineRegistry {
79 fn clone(&self) -> Self {
80 Self {
81 inner: self.inner.clone(),
82 }
83 }
84}
85
86impl RoutineRegistry {
87 pub fn builder() -> RoutineRegistryBuilder {
89 RoutineRegistryBuilder::new()
90 }
91
92 pub(crate) fn encode_query_input<T>(&self, input: &T::Input) -> BridgeResult<Vec<u8>>
94 where
95 T: 'static + BridgedQuery,
96 {
97 let input = bincode::serialize(&input).map_err(BridgeError::Encoding)?;
98 let type_id = TypeId::of::<T>();
99
100 let query_index = self
101 .inner
102 .query_ids
103 .iter()
104 .enumerate()
105 .find(|(_, m)| **m == type_id)
106 .ok_or(BridgeError::InvalidType(type_id))?
107 .0;
108
109 let incoming = Incoming {
110 query_index,
111 input: &input,
112 };
113
114 bincode::serialize(&incoming).map_err(BridgeError::Encoding)
115 }
116
117 pub(crate) fn decode_query_output<T>(&self, output: &[u8]) -> QueryResult<T>
119 where
120 T: 'static + BridgedQuery,
121 {
122 bincode::deserialize::<std::result::Result<T, T::Error>>(output)
123 .map_err(BridgeError::Encoding)
124 .map_err(T::into_query_error)?
125 .map(Rc::new)
126 }
127
128 pub(crate) fn encode_mutation_input<T>(&self, input: &T::Input) -> BridgeResult<Vec<u8>>
130 where
131 T: 'static + BridgedMutation,
132 {
133 let input = bincode::serialize(&input).map_err(BridgeError::Encoding)?;
134 let type_id = TypeId::of::<T>();
135
136 let query_index = self
137 .inner
138 .query_ids
139 .iter()
140 .enumerate()
141 .find(|(_, m)| **m == type_id)
142 .ok_or(BridgeError::InvalidType(type_id))?
143 .0;
144
145 let incoming = Incoming {
146 query_index,
147 input: &input,
148 };
149
150 bincode::serialize(&incoming).map_err(BridgeError::Encoding)
151 }
152
153 pub(crate) fn decode_mutation_output<T>(&self, output: &[u8]) -> MutationResult<T>
155 where
156 T: 'static + BridgedMutation,
157 {
158 bincode::deserialize::<std::result::Result<T, T::Error>>(output)
159 .map_err(BridgeError::Encoding)
160 .map_err(T::into_mutation_error)?
161 .map(Rc::new)
162 }
163}