swamp_script_eval/
value_ref.rs1use std::cell::{Ref, RefCell};
6use std::fmt::{Display, Formatter};
7use std::hash::Hash;
8use std::rc::Rc;
9use swamp_script_core::extra::{SparseValueId, SparseValueMap};
10use swamp_script_core::prelude::{Value, ValueError};
11use swamp_script_core::value::ValueRef;
12use swamp_script_core::value::{RustType, SPARSE_TYPE_ID};
13use tracing::info;
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 inner = self.0.borrow();
28 let result = match &*inner {
29 Value::RustValue(ref rust_type_ref, ref _rust_value) => {
30 Box::new(match rust_type_ref.number {
31 SPARSE_TYPE_ID => {
32 let sparse_map = inner
33 .downcast_rust::<SparseValueMap>()
34 .expect("must be sparsemap");
35
36 let pairs: Vec<_> = sparse_map
39 .borrow_mut()
40 .iter_mut()
41 .map(|(_k, v)| v.clone())
42 .collect();
43
44 Box::new(pairs.into_iter()) as Box<dyn Iterator<Item = ValueRef>>
45 }
46 _ => return Err(ValueError::CanNotCoerceToIterator),
47 })
48 }
49 Value::Map(ref _type_ref, seq_map) => {
50 let cloned_rc: Vec<ValueRef> = seq_map.values().cloned().collect();
52
53 Box::new(cloned_rc.into_iter()) as Box<dyn Iterator<Item = ValueRef> + 'static>
55 }
56
57 _ => {
62 info!(?inner, "not sure what this is:");
63 todo!()
64 }
65 };
66 Ok(result)
67 }
68
69 pub fn into_iter_mut_pairs(
74 self,
75 ) -> Result<Box<dyn Iterator<Item = (Value, Self)>>, ValueError> {
76 let inner = self.0.borrow();
77 let result = match &*inner {
78 Value::RustValue(ref rust_type_ref, ref _rust_value) => {
79 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 }
106 _ => todo!(),
107 };
108 Ok(result)
109 }
110 #[must_use]
111 pub fn downcast_rust_mut<T: RustType + 'static>(&self) -> Option<Rc<RefCell<Box<T>>>> {
112 match &*self.0.borrow() {
113 Value::RustValue(_rust_type_ref, rc) => {
114 let type_matches = {
115 let guard = rc.borrow();
116 (**guard).as_any().is::<T>()
117 };
118
119 if type_matches {
120 Some(unsafe { std::mem::transmute(rc.clone()) })
121 } else {
122 None
123 }
124 }
125 _ => None,
126 }
127 }
128
129 #[must_use]
130 pub fn unref(&self) -> Ref<Value> {
131 self.0.borrow()
132 }
133
134 #[must_use]
135 pub fn convert_to_string_if_needed(&self) -> String {
136 self.0.borrow().convert_to_string_if_needed()
137 }
138}
139
140impl PartialEq<Self> for ValueReference {
141 fn eq(&self, other: &Self) -> bool {
142 self.0.borrow().eq(&*other.0.borrow())
143 }
144}
145
146impl Eq for ValueReference {}
147
148impl Hash for ValueReference {
149 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
150 self.0.borrow().hash(state);
151 }
152}
153
154impl Display for ValueReference {
155 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
156 write!(f, "{}", self.0.borrow())
157 }
158}