use std::collections::BTreeMap; #[derive(Debug, Clone, PartialEq)] pub enum Value { Null, Bool(bool), Number(f64), String(String), Array(Vec), Object(BTreeMap), } impl Value { pub fn estimated_size(&self) -> usize { match self { Value::Null | Value::Bool(_) => 1, Value::Number(_) => 8, Value::String(s) => s.len(), Value::Array(arr) => arr.iter().map(|v| v.estimated_size()).sum(), Value::Object(map) => map .iter() .map(|(k, v)| k.len() + v.estimated_size()) .sum(), } } pub fn get_path(&self, path: &str) -> Option<&Value> { let path = path.strip_prefix("$").unwrap_or(path); let mut current = self; for raw_segment in path.split('.').filter(|s| !s.is_empty()) { if let Some(bracket_pos) = raw_segment.find('[') { let key = &raw_segment[..bracket_pos]; let index_str = raw_segment[bracket_pos + 1..].strip_suffix(']')?; let index: usize = index_str.parse().ok()?; if !key.is_empty() { match current { Value::Object(map) => current = map.get(key)?, _ => return None, } } match current { Value::Array(arr) => current = arr.get(index)?, _ => return None, } } else { match current { Value::Object(map) => current = map.get(raw_segment)?, _ => return None, } } } Some(current) } }