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, SparseValueMap};
11use swamp_script_core_extra::prelude::{Value, ValueError};
12use swamp_script_core_extra::value::ValueRef;
13use swamp_script_core_extra::value::{RustType, SPARSE_TYPE_ID};
14use tracing::info;
15
16#[derive(Debug, Clone)]
17pub struct ValueReference(pub ValueRef);
18
19impl ValueReference {}
20
21impl ValueReference {
22 #[inline]
23 pub fn set(&self, v: Value) {
24 *self.0.borrow_mut() = v;
25 }
26
27 pub(crate) fn into_iter_mut(self) -> Result<Box<dyn Iterator<Item = ValueRef>>, ValueError> {
28 let inner = self.0.borrow();
29 let result = match &*inner {
30 Value::RustValue(rust_type_ref, _rust_value) => {
31 Box::new(match rust_type_ref.number {
32 SPARSE_TYPE_ID => {
33 let sparse_map = inner
34 .downcast_rust::<SparseValueMap>()
35 .expect("must be sparsemap");
36
37 let pairs: Vec<_> = sparse_map
40 .borrow_mut()
41 .iter_mut()
42 .map(|(_k, v)| v.clone())
43 .collect();
44
45 Box::new(pairs.into_iter()) as Box<dyn Iterator<Item = ValueRef>>
46 }
47 _ => return Err(ValueError::CanNotCoerceToIterator),
48 })
49 }
50 Value::Map(_type_ref, seq_map) => {
51 let cloned_rc: Vec<ValueRef> = seq_map.values().cloned().collect();
53
54 Box::new(cloned_rc.into_iter()) as Box<dyn Iterator<Item = ValueRef> + 'static>
56 }
57
58 _ => {
63 info!(?inner, "not sure what this is:");
64 todo!()
65 }
66 };
67 Ok(result)
68 }
69
70 pub fn into_iter_mut_pairs(
75 self,
76 ) -> Result<Box<dyn Iterator<Item = (Value, Self)>>, ValueError> {
77 let inner = self.0.borrow();
78 let result = match &*inner {
79 Value::RustValue(rust_type_ref, _rust_value) => Box::new(match rust_type_ref.number {
80 SPARSE_TYPE_ID => {
81 let sparse_map = inner
82 .downcast_rust::<SparseValueMap>()
83 .expect("must be sparsemap");
84
85 let id_type_ref = sparse_map.borrow().rust_type_ref_for_id.clone();
86
87 let pairs: Vec<_> = sparse_map
88 .borrow_mut()
89 .iter_mut()
90 .map(|(k, v)| {
91 (
92 Value::RustValue(
93 id_type_ref.clone(),
94 Rc::new(RefCell::new(Box::new(SparseValueId(k)))),
95 ),
96 Self(v.clone()),
97 )
98 })
99 .collect();
100
101 Box::new(pairs.into_iter()) as Box<dyn Iterator<Item = (Value, Self)>>
102 }
103 _ => return Err(ValueError::CanNotCoerceToIterator),
104 }),
105 _ => todo!(),
106 };
107 Ok(result)
108 }
109 #[must_use]
110 pub fn downcast_rust_mut<T: RustType + 'static>(&self) -> Option<Rc<RefCell<Box<T>>>> {
111 match &*self.0.borrow() {
112 Value::RustValue(_rust_type_ref, rc) => {
113 let type_matches = {
114 let guard = rc.borrow();
115 (**guard).as_any().is::<T>()
116 };
117
118 if type_matches {
119 Some(unsafe { std::mem::transmute(rc.clone()) })
120 } else {
121 None
122 }
123 }
124 _ => None,
125 }
126 }
127
128 #[must_use]
129 pub fn unref(&self) -> Ref<Value> {
130 self.0.borrow()
131 }
132
133 #[must_use]
134 pub fn convert_to_string_if_needed(&self) -> String {
135 self.0.borrow().convert_to_string_if_needed()
136 }
137}
138
139impl PartialEq<Self> for ValueReference {
140 fn eq(&self, other: &Self) -> bool {
141 self.0.borrow().eq(&*other.0.borrow())
142 }
143}
144
145impl Eq for ValueReference {}
146
147impl Hash for ValueReference {
148 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
149 self.0.borrow().hash(state);
150 }
151}
152
153impl Display for ValueReference {
154 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
155 write!(f, "{}", self.0.borrow())
156 }
157}