ruvector_graph/
property.rs1use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
10#[serde(untagged)]
11pub enum PropertyValue {
12 Null,
14 Bool(bool),
16 Int(i64),
18 Float(f64),
20 String(String),
22 Array(Vec<PropertyValue>),
24 Map(HashMap<String, PropertyValue>),
26}
27
28impl PropertyValue {
29 pub fn is_null(&self) -> bool {
31 matches!(self, PropertyValue::Null)
32 }
33
34 pub fn as_bool(&self) -> Option<bool> {
36 match self {
37 PropertyValue::Bool(b) => Some(*b),
38 _ => None,
39 }
40 }
41
42 pub fn as_int(&self) -> Option<i64> {
44 match self {
45 PropertyValue::Int(i) => Some(*i),
46 _ => None,
47 }
48 }
49
50 pub fn as_float(&self) -> Option<f64> {
52 match self {
53 PropertyValue::Float(f) => Some(*f),
54 PropertyValue::Int(i) => Some(*i as f64),
55 _ => None,
56 }
57 }
58
59 pub fn as_str(&self) -> Option<&str> {
61 match self {
62 PropertyValue::String(s) => Some(s),
63 _ => None,
64 }
65 }
66
67 pub fn as_array(&self) -> Option<&Vec<PropertyValue>> {
69 match self {
70 PropertyValue::Array(arr) => Some(arr),
71 _ => None,
72 }
73 }
74
75 pub fn as_map(&self) -> Option<&HashMap<String, PropertyValue>> {
77 match self {
78 PropertyValue::Map(map) => Some(map),
79 _ => None,
80 }
81 }
82
83 pub fn type_name(&self) -> &'static str {
85 match self {
86 PropertyValue::Null => "null",
87 PropertyValue::Bool(_) => "bool",
88 PropertyValue::Int(_) => "int",
89 PropertyValue::Float(_) => "float",
90 PropertyValue::String(_) => "string",
91 PropertyValue::Array(_) => "array",
92 PropertyValue::Map(_) => "map",
93 }
94 }
95}
96
97impl From<bool> for PropertyValue {
98 fn from(b: bool) -> Self {
99 PropertyValue::Bool(b)
100 }
101}
102
103impl From<i64> for PropertyValue {
104 fn from(i: i64) -> Self {
105 PropertyValue::Int(i)
106 }
107}
108
109impl From<i32> for PropertyValue {
110 fn from(i: i32) -> Self {
111 PropertyValue::Int(i as i64)
112 }
113}
114
115impl From<f64> for PropertyValue {
116 fn from(f: f64) -> Self {
117 PropertyValue::Float(f)
118 }
119}
120
121impl From<f32> for PropertyValue {
122 fn from(f: f32) -> Self {
123 PropertyValue::Float(f as f64)
124 }
125}
126
127impl From<String> for PropertyValue {
128 fn from(s: String) -> Self {
129 PropertyValue::String(s)
130 }
131}
132
133impl From<&str> for PropertyValue {
134 fn from(s: &str) -> Self {
135 PropertyValue::String(s.to_string())
136 }
137}
138
139impl From<Vec<PropertyValue>> for PropertyValue {
140 fn from(arr: Vec<PropertyValue>) -> Self {
141 PropertyValue::Array(arr)
142 }
143}
144
145impl From<HashMap<String, PropertyValue>> for PropertyValue {
146 fn from(map: HashMap<String, PropertyValue>) -> Self {
147 PropertyValue::Map(map)
148 }
149}
150
151pub type Properties = HashMap<String, PropertyValue>;
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157
158 #[test]
159 fn test_property_value_types() {
160 let null = PropertyValue::Null;
161 assert!(null.is_null());
162
163 let bool_val = PropertyValue::Bool(true);
164 assert_eq!(bool_val.as_bool(), Some(true));
165
166 let int_val = PropertyValue::Int(42);
167 assert_eq!(int_val.as_int(), Some(42));
168 assert_eq!(int_val.as_float(), Some(42.0));
169
170 let float_val = PropertyValue::Float(3.14);
171 assert_eq!(float_val.as_float(), Some(3.14));
172
173 let str_val = PropertyValue::String("hello".to_string());
174 assert_eq!(str_val.as_str(), Some("hello"));
175 }
176
177 #[test]
178 fn test_property_conversions() {
179 let _: PropertyValue = true.into();
180 let _: PropertyValue = 42i64.into();
181 let _: PropertyValue = 42i32.into();
182 let _: PropertyValue = 3.14f64.into();
183 let _: PropertyValue = 3.14f32.into();
184 let _: PropertyValue = "test".into();
185 let _: PropertyValue = "test".to_string().into();
186 }
187
188 #[test]
189 fn test_nested_properties() {
190 let mut map = HashMap::new();
191 map.insert("nested".to_string(), PropertyValue::Int(123));
192
193 let array = vec![
194 PropertyValue::Int(1),
195 PropertyValue::Int(2),
196 PropertyValue::Int(3),
197 ];
198
199 let complex = PropertyValue::Map({
200 let mut m = HashMap::new();
201 m.insert("array".to_string(), PropertyValue::Array(array));
202 m.insert("map".to_string(), PropertyValue::Map(map));
203 m
204 });
205
206 assert!(complex.as_map().is_some());
207 }
208}