byteorm_lib/rustgen/
jsonb.rs

1use proc_macro2::TokenStream;
2use quote::quote;
3
4type Error = Box<dyn std::error::Error + Send + Sync>;
5
6pub fn generate_jsonb_ext() -> TokenStream {
7    quote! {
8        pub trait JsonbExt {
9            fn get_value<T>(&self, key: &str) -> Result<T, Box<dyn std::error::Error + Send + Sync>>
10            where T: serde::de::DeserializeOwned;
11
12            fn get_string(&self, key: &str) -> Result<String, Box<dyn std::error::Error + Send + Sync>>;
13
14            fn get_i64(&self, key: &str) -> Result<i64, Box<dyn std::error::Error + Send + Sync>>;
15            fn get_bool(&self, key: &str) -> Result<bool, Box<dyn std::error::Error + Send + Sync>>;
16
17            fn get_or_default<T>(&self, key: &str, default: T) -> T
18            where T: serde::de::DeserializeOwned;
19
20            fn has_key(&self, key: &str) -> bool;
21        }
22
23        impl JsonbExt for serde_json::Value {
24            fn get_value<T>(&self, key: &str) -> Result<T, Box<dyn std::error::Error + Send + Sync>>
25            where T: serde::de::DeserializeOwned {
26                let value = self.get(key).ok_or_else(|| {
27                    Box::<dyn std::error::Error + Send + Sync>::from(format!("Key '{}' not found", key))
28                })?;
29                serde_json::from_value(value.clone())
30                    .map_err(|e| Box::<dyn std::error::Error + Send + Sync>::from(format!("Failed to parse key '{}': {}", key, e)))
31            }
32
33            fn get_string(&self, key: &str) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
34                match self.get(key) {
35                    Some(serde_json::Value::String(s)) => Ok(s.clone()),
36                    Some(v) => serde_json::from_value(v.clone())
37                        .map_err(|e| Box::<dyn std::error::Error + Send + Sync>::from(format!("Failed to parse '{}' as string: {}", key, e))),
38                    None => Err(Box::<dyn std::error::Error + Send + Sync>::from(format!("Key '{}' not found", key))),
39                }
40            }
41
42            fn get_i64(&self, key: &str) -> Result<i64, Box<dyn std::error::Error + Send + Sync>> {
43                match self.get(key) {
44                    Some(serde_json::Value::Number(n)) => n.as_i64().ok_or_else(|| {
45                        Box::<dyn std::error::Error + Send + Sync>::from(format!("Key '{}' is not a valid i64", key))
46                    }),
47                    Some(v) => serde_json::from_value(v.clone())
48                        .map_err(|e| Box::<dyn std::error::Error + Send + Sync>::from(format!("Failed to parse '{}' as i64: {}", key, e))),
49                    None => Err(Box::<dyn std::error::Error + Send + Sync>::from(format!("Key '{}' not found", key))),
50                }
51            }
52
53            fn get_bool(&self, key: &str) -> Result<bool, Box<dyn std::error::Error + Send + Sync>> {
54                match self.get(key) {
55                    Some(serde_json::Value::Bool(b)) => Ok(*b),
56                    Some(v) => serde_json::from_value(v.clone())
57                        .map_err(|e| Box::<dyn std::error::Error + Send + Sync>::from(format!("Failed to parse '{}' as bool: {}", key, e))),
58                    None => Err(Box::<dyn std::error::Error + Send + Sync>::from(format!("Key '{}' not found", key))),
59                }
60            }
61
62            fn get_or_default<T>(&self, key: &str, default: T) -> T
63            where T: serde::de::DeserializeOwned {
64                self.get_value(key).unwrap_or(default)
65            }
66
67            fn has_key(&self, key: &str) -> bool {
68                self.get(key).is_some()
69            }
70        }
71    }
72}