Skip to main content

runar_serializer/
registry.rs

1//! Global decryptor registry used by ArcValue.
2use std::any::{Any, TypeId};
3use std::collections::HashMap;
4use std::sync::Arc;
5
6use anyhow::Result;
7use dashmap::DashMap;
8use once_cell::sync::Lazy;
9use serde_json::Value as JsonValue;
10
11use crate::traits::{KeyStore, RunarDecrypt};
12use crate::ArcValue;
13use serde::de::DeserializeOwned;
14
15/// Function pointer stored in the registry.
16pub type DecryptFn = fn(&[u8], &Arc<KeyStore>) -> Result<Box<dyn Any + Send + Sync>>;
17
18/// Function pointer for JSON conversion stored in the registry.
19pub type ToJsonFn = fn(&[u8]) -> Result<JsonValue>;
20
21/// Global, thread-safe map: PlainTypeId -> decrypt function.
22static STRUCT_REGISTRY: Lazy<DashMap<TypeId, DecryptFn>> = Lazy::new(DashMap::new);
23
24/// Global, thread-safe map: Type name (&'static str) -> JSON conversion function.
25/// Using &'static str avoids per-registration heap allocations.
26static JSON_REGISTRY: Lazy<DashMap<&'static str, ToJsonFn>> = Lazy::new(DashMap::new);
27
28/// Register a decryptor for `Plain` using the encrypted representation `Enc`.
29///
30/// This is intended to be invoked automatically by the `Encrypt` derive macro
31/// through a `#[ctor]`-annotated function, so user code never calls it
32/// directly.
33pub fn register_decrypt<Plain, Enc>()
34where
35    Plain: 'static + Send + Sync,
36    Enc: 'static + RunarDecrypt<Decrypted = Plain> + DeserializeOwned,
37{
38    // Mono-morphise a concrete decryptor function and insert it.
39    fn decrypt_impl<Plain, Enc>(
40        bytes: &[u8],
41        ks: &Arc<KeyStore>,
42    ) -> Result<Box<dyn Any + Send + Sync>>
43    where
44        Plain: 'static + Send + Sync,
45        Enc: 'static + RunarDecrypt<Decrypted = Plain> + DeserializeOwned,
46    {
47        let enc: Enc = serde_cbor::from_slice(bytes)?;
48        let plain = enc.decrypt_with_keystore(ks)?;
49        Ok(Box::new(plain))
50    }
51
52    STRUCT_REGISTRY.insert(
53        TypeId::of::<Plain>(),
54        decrypt_impl::<Plain, Enc> as DecryptFn,
55    );
56}
57
58/// Register a JSON conversion function for type `T`.
59///
60/// This is intended to be invoked automatically by the `Plain` and `Encrypt` derive macros
61/// through a `#[ctor]`-annotated function, so user code never calls it directly.
62pub fn register_to_json<T>()
63where
64    T: 'static + serde::Serialize + serde::de::DeserializeOwned,
65{
66    // Mono-morphise a concrete JSON conversion function and insert it.
67    fn to_json_impl<T>(bytes: &[u8]) -> Result<JsonValue>
68    where
69        T: 'static + serde::Serialize + serde::de::DeserializeOwned,
70    {
71        let value: T = serde_cbor::from_slice(bytes)?;
72        serde_json::to_value(&value).map_err(anyhow::Error::from)
73    }
74
75    let type_name: &'static str = std::any::type_name::<T>();
76    let func = to_json_impl::<T>;
77
78    JSON_REGISTRY.insert(type_name, func);
79}
80
81/// Attempt to decrypt the payload into `T` using the registered decryptor.
82/// Returns an error if no decryptor is found.
83pub fn try_decrypt_into<T>(bytes: &[u8], ks: &Arc<KeyStore>) -> Result<T>
84where
85    T: 'static + Send + Sync,
86{
87    // Minimize time under the map lock: copy out the function pointer, then drop guard.
88    let decrypt_fn: DecryptFn = {
89        let entry = STRUCT_REGISTRY.get(&TypeId::of::<T>()).ok_or_else(|| {
90            anyhow::anyhow!(
91                "No decryptor registered for type {}",
92                std::any::type_name::<T>()
93            )
94        })?;
95        *entry.value()
96    };
97
98    let any_plain = (decrypt_fn)(bytes, ks)?;
99    // Downcast into the concrete type we need.
100    any_plain.downcast::<T>().map(|boxed| *boxed).map_err(|_| {
101        anyhow::anyhow!(
102            "Decryptor returned wrong type for {}",
103            std::any::type_name::<T>()
104        )
105    })
106}
107
108/// Get a JSON conversion function for a type name.
109/// Returns None if no converter is registered for the type name.
110pub fn get_json_converter(type_name: &str) -> Option<ToJsonFn> {
111    // DashMap supports borrowed lookups; this avoids allocating a String key
112    JSON_REGISTRY.get(type_name).map(|entry| *entry.value())
113}
114
115// Common JSON converters for Vec<V> and HashMap<K, V>
116// Using all primitive variants of K and V where V can be Vec and Map also.
117// Use CTOR to register the converters
118
119#[ctor::ctor]
120fn register_vec_arcvalue_converter() {
121    register_to_json::<Vec<ArcValue>>();
122    register_to_json::<HashMap<String, ArcValue>>();
123    register_to_json::<Vec<HashMap<String, ArcValue>>>();
124    register_to_json::<HashMap<String, Vec<ArcValue>>>();
125    register_to_json::<HashMap<String, HashMap<String, ArcValue>>>();
126    register_to_json::<Vec<Vec<ArcValue>>>();
127    register_to_json::<Vec<HashMap<String, ArcValue>>>();
128    register_to_json::<HashMap<String, Vec<ArcValue>>>();
129    register_to_json::<HashMap<String, HashMap<String, ArcValue>>>();
130}
131
132// Vec converters for primitive types
133#[ctor::ctor]
134fn register_vec_primitive_converters() {
135    // Vec of primitive types - ALL combinations
136    register_to_json::<Vec<i8>>();
137    register_to_json::<Vec<i16>>();
138    register_to_json::<Vec<i32>>();
139    register_to_json::<Vec<i64>>();
140    register_to_json::<Vec<i128>>();
141    register_to_json::<Vec<u8>>();
142    register_to_json::<Vec<u16>>();
143    register_to_json::<Vec<u32>>();
144    register_to_json::<Vec<u64>>();
145    register_to_json::<Vec<u128>>();
146    register_to_json::<Vec<f32>>();
147    register_to_json::<Vec<f64>>();
148    register_to_json::<Vec<bool>>();
149    register_to_json::<Vec<char>>();
150    register_to_json::<Vec<String>>();
151    register_to_json::<Vec<Vec<u8>>>();
152}
153
154// HashMap converters for primitive types
155#[ctor::ctor]
156fn register_hashmap_primitive_converters() {
157    // HashMap<String, primitive> converters - ALL combinations
158    register_to_json::<HashMap<String, i8>>();
159    register_to_json::<HashMap<String, i16>>();
160    register_to_json::<HashMap<String, i32>>();
161    register_to_json::<HashMap<String, i64>>();
162    register_to_json::<HashMap<String, i128>>();
163    register_to_json::<HashMap<String, u8>>();
164    register_to_json::<HashMap<String, u16>>();
165    register_to_json::<HashMap<String, u32>>();
166    register_to_json::<HashMap<String, u64>>();
167    register_to_json::<HashMap<String, u128>>();
168    register_to_json::<HashMap<String, f32>>();
169    register_to_json::<HashMap<String, f64>>();
170    register_to_json::<HashMap<String, bool>>();
171    register_to_json::<HashMap<String, char>>();
172    register_to_json::<HashMap<String, String>>();
173    register_to_json::<HashMap<String, Vec<u8>>>();
174}
175
176// Nested container converters - ALL combinations
177#[ctor::ctor]
178fn register_nested_container_converters() {
179    // Vec of Vec - ALL primitive combinations
180    register_to_json::<Vec<Vec<i8>>>();
181    register_to_json::<Vec<Vec<i16>>>();
182    register_to_json::<Vec<Vec<i32>>>();
183    register_to_json::<Vec<Vec<i64>>>();
184    register_to_json::<Vec<Vec<i128>>>();
185    register_to_json::<Vec<Vec<u8>>>();
186    register_to_json::<Vec<Vec<u16>>>();
187    register_to_json::<Vec<Vec<u32>>>();
188    register_to_json::<Vec<Vec<u64>>>();
189    register_to_json::<Vec<Vec<u128>>>();
190    register_to_json::<Vec<Vec<f32>>>();
191    register_to_json::<Vec<Vec<f64>>>();
192    register_to_json::<Vec<Vec<bool>>>();
193    register_to_json::<Vec<Vec<char>>>();
194    register_to_json::<Vec<Vec<String>>>();
195    register_to_json::<Vec<Vec<Vec<u8>>>>();
196
197    // Vec of HashMap - ALL primitive combinations
198    register_to_json::<Vec<HashMap<String, i8>>>();
199    register_to_json::<Vec<HashMap<String, i16>>>();
200    register_to_json::<Vec<HashMap<String, i32>>>();
201    register_to_json::<Vec<HashMap<String, i64>>>();
202    register_to_json::<Vec<HashMap<String, i128>>>();
203    register_to_json::<Vec<HashMap<String, u8>>>();
204    register_to_json::<Vec<HashMap<String, u16>>>();
205    register_to_json::<Vec<HashMap<String, u32>>>();
206    register_to_json::<Vec<HashMap<String, u64>>>();
207    register_to_json::<Vec<HashMap<String, u128>>>();
208    register_to_json::<Vec<HashMap<String, f32>>>();
209    register_to_json::<Vec<HashMap<String, f64>>>();
210    register_to_json::<Vec<HashMap<String, bool>>>();
211    register_to_json::<Vec<HashMap<String, char>>>();
212    register_to_json::<Vec<HashMap<String, String>>>();
213    register_to_json::<Vec<HashMap<String, Vec<u8>>>>();
214
215    // HashMap of Vec - ALL primitive combinations
216    register_to_json::<HashMap<String, Vec<i8>>>();
217    register_to_json::<HashMap<String, Vec<i16>>>();
218    register_to_json::<HashMap<String, Vec<i32>>>();
219    register_to_json::<HashMap<String, Vec<i64>>>();
220    register_to_json::<HashMap<String, Vec<i128>>>();
221    register_to_json::<HashMap<String, Vec<u8>>>();
222    register_to_json::<HashMap<String, Vec<u16>>>();
223    register_to_json::<HashMap<String, Vec<u32>>>();
224    register_to_json::<HashMap<String, Vec<u64>>>();
225    register_to_json::<HashMap<String, Vec<u128>>>();
226    register_to_json::<HashMap<String, Vec<f32>>>();
227    register_to_json::<HashMap<String, Vec<f64>>>();
228    register_to_json::<HashMap<String, Vec<bool>>>();
229    register_to_json::<HashMap<String, Vec<char>>>();
230    register_to_json::<HashMap<String, Vec<String>>>();
231    register_to_json::<HashMap<String, Vec<Vec<u8>>>>();
232
233    // HashMap of HashMap - ALL primitive combinations
234    register_to_json::<HashMap<String, HashMap<String, i8>>>();
235    register_to_json::<HashMap<String, HashMap<String, i16>>>();
236    register_to_json::<HashMap<String, HashMap<String, i32>>>();
237    register_to_json::<HashMap<String, HashMap<String, i64>>>();
238    register_to_json::<HashMap<String, HashMap<String, i128>>>();
239    register_to_json::<HashMap<String, HashMap<String, u8>>>();
240    register_to_json::<HashMap<String, HashMap<String, u16>>>();
241    register_to_json::<HashMap<String, HashMap<String, u32>>>();
242    register_to_json::<HashMap<String, HashMap<String, u64>>>();
243    register_to_json::<HashMap<String, HashMap<String, u128>>>();
244    register_to_json::<HashMap<String, HashMap<String, f32>>>();
245    register_to_json::<HashMap<String, HashMap<String, f64>>>();
246    register_to_json::<HashMap<String, HashMap<String, bool>>>();
247    register_to_json::<HashMap<String, HashMap<String, char>>>();
248    register_to_json::<HashMap<String, HashMap<String, String>>>();
249    register_to_json::<HashMap<String, HashMap<String, Vec<u8>>>>();
250}
251
252// Triple nested container converters - ALL combinations
253#[ctor::ctor]
254fn register_triple_nested_container_converters() {
255    // Vec of Vec of Vec - ALL primitive combinations
256    register_to_json::<Vec<Vec<Vec<i8>>>>();
257    register_to_json::<Vec<Vec<Vec<i16>>>>();
258    register_to_json::<Vec<Vec<Vec<i32>>>>();
259    register_to_json::<Vec<Vec<Vec<i64>>>>();
260    register_to_json::<Vec<Vec<Vec<i128>>>>();
261    register_to_json::<Vec<Vec<Vec<u8>>>>();
262    register_to_json::<Vec<Vec<Vec<u16>>>>();
263    register_to_json::<Vec<Vec<Vec<u32>>>>();
264    register_to_json::<Vec<Vec<Vec<u64>>>>();
265    register_to_json::<Vec<Vec<Vec<u128>>>>();
266    register_to_json::<Vec<Vec<Vec<f32>>>>();
267    register_to_json::<Vec<Vec<Vec<f64>>>>();
268    register_to_json::<Vec<Vec<Vec<bool>>>>();
269    register_to_json::<Vec<Vec<Vec<char>>>>();
270    register_to_json::<Vec<Vec<Vec<String>>>>();
271    register_to_json::<Vec<Vec<Vec<Vec<u8>>>>>();
272
273    // Vec of Vec of HashMap - ALL primitive combinations
274    register_to_json::<Vec<Vec<HashMap<String, i8>>>>();
275    register_to_json::<Vec<Vec<HashMap<String, i16>>>>();
276    register_to_json::<Vec<Vec<HashMap<String, i32>>>>();
277    register_to_json::<Vec<Vec<HashMap<String, i64>>>>();
278    register_to_json::<Vec<Vec<HashMap<String, i128>>>>();
279    register_to_json::<Vec<Vec<HashMap<String, u8>>>>();
280    register_to_json::<Vec<Vec<HashMap<String, u16>>>>();
281    register_to_json::<Vec<Vec<HashMap<String, u32>>>>();
282    register_to_json::<Vec<Vec<HashMap<String, u64>>>>();
283    register_to_json::<Vec<Vec<HashMap<String, u128>>>>();
284    register_to_json::<Vec<Vec<HashMap<String, f32>>>>();
285    register_to_json::<Vec<Vec<HashMap<String, f64>>>>();
286    register_to_json::<Vec<Vec<HashMap<String, bool>>>>();
287    register_to_json::<Vec<Vec<HashMap<String, char>>>>();
288    register_to_json::<Vec<Vec<HashMap<String, String>>>>();
289    register_to_json::<Vec<Vec<HashMap<String, Vec<u8>>>>>();
290
291    // Vec of HashMap of Vec - ALL primitive combinations
292    register_to_json::<Vec<HashMap<String, Vec<i8>>>>();
293    register_to_json::<Vec<HashMap<String, Vec<i16>>>>();
294    register_to_json::<Vec<HashMap<String, Vec<i32>>>>();
295    register_to_json::<Vec<HashMap<String, Vec<i64>>>>();
296    register_to_json::<Vec<HashMap<String, Vec<i128>>>>();
297    register_to_json::<Vec<HashMap<String, Vec<u8>>>>();
298    register_to_json::<Vec<HashMap<String, Vec<u16>>>>();
299    register_to_json::<Vec<HashMap<String, Vec<u32>>>>();
300    register_to_json::<Vec<HashMap<String, Vec<u64>>>>();
301    register_to_json::<Vec<HashMap<String, Vec<u128>>>>();
302    register_to_json::<Vec<HashMap<String, Vec<f32>>>>();
303    register_to_json::<Vec<HashMap<String, Vec<f64>>>>();
304    register_to_json::<Vec<HashMap<String, Vec<bool>>>>();
305    register_to_json::<Vec<HashMap<String, Vec<char>>>>();
306    register_to_json::<Vec<HashMap<String, Vec<String>>>>();
307    register_to_json::<Vec<HashMap<String, Vec<Vec<u8>>>>>();
308
309    // Vec of HashMap of HashMap - ALL primitive combinations
310    register_to_json::<Vec<HashMap<String, HashMap<String, i8>>>>();
311    register_to_json::<Vec<HashMap<String, HashMap<String, i16>>>>();
312    register_to_json::<Vec<HashMap<String, HashMap<String, i32>>>>();
313    register_to_json::<Vec<HashMap<String, HashMap<String, i64>>>>();
314    register_to_json::<Vec<HashMap<String, HashMap<String, i128>>>>();
315    register_to_json::<Vec<HashMap<String, HashMap<String, u8>>>>();
316    register_to_json::<Vec<HashMap<String, HashMap<String, u16>>>>();
317    register_to_json::<Vec<HashMap<String, HashMap<String, u32>>>>();
318    register_to_json::<Vec<HashMap<String, HashMap<String, u64>>>>();
319    register_to_json::<Vec<HashMap<String, HashMap<String, u128>>>>();
320    register_to_json::<Vec<HashMap<String, HashMap<String, f32>>>>();
321    register_to_json::<Vec<HashMap<String, HashMap<String, f64>>>>();
322    register_to_json::<Vec<HashMap<String, HashMap<String, bool>>>>();
323    register_to_json::<Vec<HashMap<String, HashMap<String, char>>>>();
324    register_to_json::<Vec<HashMap<String, HashMap<String, String>>>>();
325    register_to_json::<Vec<HashMap<String, HashMap<String, Vec<u8>>>>>();
326
327    // HashMap of Vec of Vec - ALL primitive combinations
328    register_to_json::<HashMap<String, Vec<Vec<i8>>>>();
329    register_to_json::<HashMap<String, Vec<Vec<i16>>>>();
330    register_to_json::<HashMap<String, Vec<Vec<i32>>>>();
331    register_to_json::<HashMap<String, Vec<Vec<i64>>>>();
332    register_to_json::<HashMap<String, Vec<Vec<i128>>>>();
333    register_to_json::<HashMap<String, Vec<Vec<u8>>>>();
334    register_to_json::<HashMap<String, Vec<Vec<u16>>>>();
335    register_to_json::<HashMap<String, Vec<Vec<u32>>>>();
336    register_to_json::<HashMap<String, Vec<Vec<u64>>>>();
337    register_to_json::<HashMap<String, Vec<Vec<u128>>>>();
338    register_to_json::<HashMap<String, Vec<Vec<f32>>>>();
339    register_to_json::<HashMap<String, Vec<Vec<f64>>>>();
340    register_to_json::<HashMap<String, Vec<Vec<bool>>>>();
341    register_to_json::<HashMap<String, Vec<Vec<char>>>>();
342    register_to_json::<HashMap<String, Vec<Vec<String>>>>();
343    register_to_json::<HashMap<String, Vec<Vec<Vec<u8>>>>>();
344
345    // HashMap of Vec of HashMap - ALL primitive combinations
346    register_to_json::<HashMap<String, Vec<HashMap<String, i8>>>>();
347    register_to_json::<HashMap<String, Vec<HashMap<String, i16>>>>();
348    register_to_json::<HashMap<String, Vec<HashMap<String, i32>>>>();
349    register_to_json::<HashMap<String, Vec<HashMap<String, i64>>>>();
350    register_to_json::<HashMap<String, Vec<HashMap<String, i128>>>>();
351    register_to_json::<HashMap<String, Vec<HashMap<String, u8>>>>();
352    register_to_json::<HashMap<String, Vec<HashMap<String, u16>>>>();
353    register_to_json::<HashMap<String, Vec<HashMap<String, u32>>>>();
354    register_to_json::<HashMap<String, Vec<HashMap<String, u64>>>>();
355    register_to_json::<HashMap<String, Vec<HashMap<String, u128>>>>();
356    register_to_json::<HashMap<String, Vec<HashMap<String, f32>>>>();
357    register_to_json::<HashMap<String, Vec<HashMap<String, f64>>>>();
358    register_to_json::<HashMap<String, Vec<HashMap<String, bool>>>>();
359    register_to_json::<HashMap<String, Vec<HashMap<String, char>>>>();
360    register_to_json::<HashMap<String, Vec<HashMap<String, String>>>>();
361    register_to_json::<HashMap<String, Vec<HashMap<String, Vec<u8>>>>>();
362
363    // HashMap of HashMap of Vec - ALL primitive combinations
364    register_to_json::<HashMap<String, HashMap<String, Vec<i8>>>>();
365    register_to_json::<HashMap<String, HashMap<String, Vec<i16>>>>();
366    register_to_json::<HashMap<String, HashMap<String, Vec<i32>>>>();
367    register_to_json::<HashMap<String, HashMap<String, Vec<i64>>>>();
368    register_to_json::<HashMap<String, HashMap<String, Vec<i128>>>>();
369    register_to_json::<HashMap<String, HashMap<String, Vec<u8>>>>();
370    register_to_json::<HashMap<String, HashMap<String, Vec<u16>>>>();
371    register_to_json::<HashMap<String, HashMap<String, Vec<u32>>>>();
372    register_to_json::<HashMap<String, HashMap<String, Vec<u64>>>>();
373    register_to_json::<HashMap<String, HashMap<String, Vec<u128>>>>();
374    register_to_json::<HashMap<String, HashMap<String, Vec<f32>>>>();
375    register_to_json::<HashMap<String, HashMap<String, Vec<f64>>>>();
376    register_to_json::<HashMap<String, HashMap<String, Vec<bool>>>>();
377    register_to_json::<HashMap<String, HashMap<String, Vec<char>>>>();
378    register_to_json::<HashMap<String, HashMap<String, Vec<String>>>>();
379    register_to_json::<HashMap<String, HashMap<String, Vec<Vec<u8>>>>>();
380
381    // HashMap of HashMap of HashMap - ALL primitive combinations
382    register_to_json::<HashMap<String, HashMap<String, HashMap<String, i8>>>>();
383    register_to_json::<HashMap<String, HashMap<String, HashMap<String, i16>>>>();
384    register_to_json::<HashMap<String, HashMap<String, HashMap<String, i32>>>>();
385    register_to_json::<HashMap<String, HashMap<String, HashMap<String, i64>>>>();
386    register_to_json::<HashMap<String, HashMap<String, HashMap<String, i128>>>>();
387    register_to_json::<HashMap<String, HashMap<String, HashMap<String, u8>>>>();
388    register_to_json::<HashMap<String, HashMap<String, HashMap<String, u16>>>>();
389    register_to_json::<HashMap<String, HashMap<String, HashMap<String, u32>>>>();
390    register_to_json::<HashMap<String, HashMap<String, HashMap<String, u64>>>>();
391    register_to_json::<HashMap<String, HashMap<String, HashMap<String, u128>>>>();
392    register_to_json::<HashMap<String, HashMap<String, HashMap<String, f32>>>>();
393    register_to_json::<HashMap<String, HashMap<String, HashMap<String, f64>>>>();
394    register_to_json::<HashMap<String, HashMap<String, HashMap<String, bool>>>>();
395    register_to_json::<HashMap<String, HashMap<String, HashMap<String, char>>>>();
396    register_to_json::<HashMap<String, HashMap<String, HashMap<String, String>>>>();
397    register_to_json::<HashMap<String, HashMap<String, HashMap<String, Vec<u8>>>>>();
398}