byteorm_lib/rustgen/
jsonb.rs1use 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}