swamp_script_eval/
value_ref.rs1use std::cell::{Ref, RefCell};
7use std::fmt::{Display, Formatter};
8use std::hash::Hash;
9use std::rc::Rc;
10use swamp_script_core_extra::extra::SparseValueId;
11use swamp_script_core_extra::prelude::{Value, ValueError};
12use swamp_script_core_extra::value::RustType;
13use swamp_script_core_extra::value::ValueRef;
14
15#[derive(Debug, Clone)]
16pub struct ValueReference(pub ValueRef);
17
18impl ValueReference {}
19
20impl ValueReference {
21 #[inline]
22 pub fn set(&self, v: Value) {
23 *self.0.borrow_mut() = v;
24 }
25
26 pub(crate) fn into_iter_mut(self) -> Result<Box<dyn Iterator<Item = ValueRef>>, ValueError> {
27 let mut inner = self.0.borrow_mut();
28 let result = match &mut *inner {
29 Value::Sparse(_rust_type_ref, sparse_map) => {
30 let pairs: Vec<_> = sparse_map.iter_mut().map(|(_k, v)| v.clone()).collect();
31
32 Box::new(pairs.into_iter()) as Box<dyn Iterator<Item = ValueRef>>
33 }
34 Value::Map(_type_ref, seq_map) => {
35 let cloned_rc: Vec<ValueRef> = seq_map.values().cloned().collect();
37
38 Box::new(cloned_rc.into_iter()) as Box<dyn Iterator<Item = ValueRef> + 'static>
40 }
41 Value::Vec(_vec_type, values) => {
42 let cloned_rc: Vec<ValueRef> = values.iter().cloned().collect();
44
45 Box::new(cloned_rc.into_iter()) as Box<dyn Iterator<Item = ValueRef> + 'static>
47 }
48 _ => {
49 todo!()
50 }
51 };
52 Ok(result)
53 }
54
55 pub fn into_iter_mut_pairs(
60 self,
61 ) -> Result<Box<dyn Iterator<Item = (Value, Self)>>, ValueError> {
62 let mut inner = self.0.borrow_mut();
63 let result = match &mut *inner {
64 Value::Sparse(_rust_type_ref, sparse_map) => {
65 let id_type_ref = sparse_map.rust_type_ref_for_id.clone();
66
67 let pairs: Vec<_> = sparse_map
68 .iter_mut()
69 .map(|(k, v)| {
70 (
71 Value::RustValue(
72 id_type_ref.clone(),
73 Rc::new(RefCell::new(Box::new(SparseValueId(k)))),
74 ),
75 Self(v.clone()),
76 )
77 })
78 .collect();
79
80 Box::new(pairs.into_iter()) as Box<dyn Iterator<Item = (Value, Self)>>
81 }
82 _ => return Err(ValueError::CanNotCoerceToIterator),
83 };
84 Ok(result)
85 }
86 #[must_use]
87 pub fn downcast_rust_mut<T: RustType + 'static>(&self) -> Option<Rc<RefCell<Box<T>>>> {
88 match &*self.0.borrow() {
89 Value::RustValue(_rust_type_ref, rc) => {
90 let type_matches = {
91 let guard = rc.borrow();
92 (**guard).as_any().is::<T>()
93 };
94
95 if type_matches {
96 Some(unsafe { std::mem::transmute(rc.clone()) })
97 } else {
98 None
99 }
100 }
101 _ => None,
102 }
103 }
104
105 #[must_use]
106 pub fn unref(&self) -> Ref<Value> {
107 self.0.borrow()
108 }
109
110 #[must_use]
111 pub fn convert_to_string_if_needed(&self) -> String {
112 self.0.borrow().convert_to_string_if_needed()
113 }
114}
115
116impl PartialEq<Self> for ValueReference {
117 fn eq(&self, other: &Self) -> bool {
118 self.0.borrow().eq(&*other.0.borrow())
119 }
120}
121
122impl Eq for ValueReference {}
123
124impl Hash for ValueReference {
125 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
126 self.0.borrow().hash(state);
127 }
128}
129
130impl Display for ValueReference {
131 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
132 write!(f, "{}", self.0.borrow())
133 }
134}