simple_expressions/types/
dict.rs1use crate::types::error::{Error, Result};
2use crate::types::object::Object;
3use crate::types::primitive::Primitive;
4use crate::types::value::Value;
5use crate::types::{function, list};
6
7use crate::types::function::method0;
8use std::any::Any;
9use std::collections::BTreeMap;
10use std::rc::Rc;
11
12pub fn new(map: BTreeMap<String, Value>) -> Value {
13 Value::Object(Rc::new(DictObject::new(map)))
14}
15pub fn new_string_dict(map: BTreeMap<String, String>) -> DictObject {
16 DictObject {
17 map: map.into_iter().map(|(k, v)| (k, Value::Primitive(Primitive::Str(v)))).collect(),
18 }
19}
20pub struct DictObject {
21 map: BTreeMap<String, Value>,
22}
23
24impl DictObject {
25 pub fn new(map: BTreeMap<String, Value>) -> DictObject {
26 DictObject { map }
27 }
28}
29
30impl Object for DictObject {
31 fn type_name(&self) -> &'static str {
32 "dict"
33 }
34 fn get_member(&self, name: &str) -> Result<Value> {
35 match name {
36 "length" => Ok(Value::from(self.map.len() as i64)),
37 "keys" => {
38 let keys: Vec<Value> = self.map.keys().cloned().map(Value::from).collect();
39 Ok(function::method0(move || Ok(list::new(keys.clone()))))
40 }
41 "values" => {
42 let vals: Vec<Value> = self.map.values().cloned().collect();
43 Ok(method0(move || Ok(list::new(vals.clone()))))
44 }
45 "contains" => {
46 let base = self.map.clone();
47 Ok(function::method1(move |arg: &Value| {
48 if let Value::Primitive(Primitive::Str(s)) = arg {
49 Ok(Value::from(base.contains_key(s)))
50 } else {
51 Err(Error::TypeMismatch("contains expects a string".into()))
52 }
53 }))
54 }
55 "get" => {
56 let base = self.map.clone();
57 Ok(function::new(std::rc::Rc::new(move |args: &[Value]| {
58 if args.len() != 2 {
59 return Err(Error::EvaluationFailed("expected 2 args".into()));
60 }
61 let key = match &args[0] {
62 Value::Primitive(Primitive::Str(s)) => s.clone(),
63 _ => return Err(Error::TypeMismatch("get expects string key".into())),
64 };
65 if let Some(v) = base.get(&key) { Ok(v.clone()) } else { Ok(args[1].clone()) }
66 })))
67 }
68 _ => Err(Error::UnknownMember {
69 type_name: "dict".into(),
70 member: name.to_string(),
71 }),
72 }
73 }
74
75 fn get_key_value(&self, key: &str) -> Result<Value> {
76 self.map.get(key).cloned().ok_or(Error::NoSuchKey(key.to_string()))
77 }
78
79 fn as_string(&self) -> Option<String> {
80 Some(format!("{{{}}}", self.map.iter().map(|(k, v)| format!("{}: {}", k, v)).collect::<Vec<_>>().join(", ")))
81 }
82
83 fn as_bool(&self) -> Option<bool> {
84 Some(!self.map.is_empty())
85 }
86
87 fn equals(&self, other: &Value) -> bool {
88 if let Value::Object(other_obj) = other
89 && let Some(other_dict) = other_obj.as_any().downcast_ref::<DictObject>()
90 {
91 self.map == other_dict.map
92 } else {
93 false
94 }
95 }
96
97 fn as_any(&self) -> &dyn Any {
98 self
99 }
100
101 fn as_any_mut(&mut self) -> &mut dyn Any {
102 self
103 }
104}