micromegas_transit/
value.rs1use anyhow::{Result, bail};
2use std::sync::Arc;
3
4#[derive(Debug, Clone)]
5pub struct Object {
6 pub type_name: Arc<String>,
7 pub members: Vec<(Arc<String>, Value)>,
8}
9
10impl Object {
11 pub fn get<T>(&self, member_name: &str) -> Result<T>
12 where
13 T: TransitValue,
14 {
15 for m in &self.members {
16 if *m.0 == member_name {
17 return T::get(&m.1);
18 }
19 }
20 bail!("member {} not found in {:?}", member_name, self);
21 }
22
23 pub fn get_ref(&self, member_name: &str) -> Result<&Value> {
24 for m in &self.members {
25 if *m.0 == member_name {
26 return Ok(&m.1);
27 }
28 }
29 bail!("member {} not found", member_name);
30 }
31}
32
33pub trait TransitValue {
34 fn get(value: &Value) -> Result<Self>
35 where
36 Self: Sized;
37}
38
39impl TransitValue for u8 {
40 fn get(value: &Value) -> Result<Self> {
41 if let Value::U8(val) = value {
42 Ok(*val)
43 } else {
44 bail!("bad type cast u8 for value {:?}", value);
45 }
46 }
47}
48
49impl TransitValue for u32 {
50 fn get(value: &Value) -> Result<Self> {
51 match value {
52 Value::U32(val) => Ok(*val),
53 Value::U8(val) => Ok(Self::from(*val)),
54 _ => {
55 bail!("bad type cast u32 for value {:?}", value);
56 }
57 }
58 }
59}
60
61impl TransitValue for u64 {
62 fn get(value: &Value) -> Result<Self> {
63 match value {
64 Value::I64(val) => Ok(*val as Self),
65 Value::U64(val) => Ok(*val),
66 _ => {
67 bail!("bad type cast u64 for value {:?}", value)
68 }
69 }
70 }
71}
72
73impl TransitValue for i64 {
74 #[allow(clippy::cast_possible_wrap)]
75 fn get(value: &Value) -> Result<Self> {
76 match value {
77 Value::I64(val) => Ok(*val),
78 Value::U64(val) => Ok(*val as Self),
79 _ => {
80 bail!("bad type cast i64 for value {:?}", value)
81 }
82 }
83 }
84}
85
86impl TransitValue for f64 {
87 fn get(value: &Value) -> Result<Self> {
88 if let Value::F64(val) = value {
89 Ok(*val)
90 } else {
91 bail!("bad type cast f64 for value {:?}", value);
92 }
93 }
94}
95
96impl TransitValue for Arc<String> {
97 fn get(value: &Value) -> Result<Self> {
98 if let Value::String(val) = value {
99 Ok(val.clone())
100 } else {
101 bail!("bad type cast String for value {:?}", value);
102 }
103 }
104}
105
106impl TransitValue for Arc<Object> {
107 fn get(value: &Value) -> Result<Self> {
108 if let Value::Object(val) = value {
109 Ok(val.clone())
110 } else {
111 bail!("bad type cast String for value {:?}", value);
112 }
113 }
114}
115
116#[derive(Debug, Clone)]
117pub enum Value {
118 String(Arc<String>),
119 Object(Arc<Object>),
120 U8(u8),
121 U32(u32),
122 U64(u64),
123 I64(i64),
124 F64(f64),
125 None,
126}
127
128impl Value {
129 pub fn as_str(&self) -> Option<&str> {
130 if let Value::String(s) = &self {
131 Some(s.as_str())
132 } else {
133 None
134 }
135 }
136}