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;
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 mut inner = self.0.borrow_mut();
29 let result = match &mut *inner {
30 Value::Sparse(_rust_type_ref, sparse_map) => {
31 let pairs: Vec<_> = sparse_map.iter_mut().map(|(_k, v)| v.clone()).collect();
32
33 Box::new(pairs.into_iter()) as Box<dyn Iterator<Item = ValueRef>>
34 }
35 Value::Map(_type_ref, seq_map) => {
36 let cloned_rc: Vec<ValueRef> = seq_map.values().cloned().collect();
38
39 Box::new(cloned_rc.into_iter()) as Box<dyn Iterator<Item = ValueRef> + 'static>
41 }
42 Value::Vec(_vec_type, values) => {
43 let cloned_rc: Vec<ValueRef> = values.iter().cloned().collect();
45
46 Box::new(cloned_rc.into_iter()) as Box<dyn Iterator<Item = ValueRef> + 'static>
48 }
49 _ => {
50 info!(?inner, "not sure what this is:");
51 todo!()
52 }
53 };
54 Ok(result)
55 }
56
57 pub fn into_iter_mut_pairs(
62 self,
63 ) -> Result<Box<dyn Iterator<Item = (Value, Self)>>, ValueError> {
64 let mut inner = self.0.borrow_mut();
65 let result = match &mut *inner {
66 Value::Sparse(_rust_type_ref, sparse_map) => {
67 let id_type_ref = sparse_map.rust_type_ref_for_id.clone();
68
69 let pairs: Vec<_> = sparse_map
70 .iter_mut()
71 .map(|(k, v)| {
72 (
73 Value::RustValue(
74 id_type_ref.clone(),
75 Rc::new(RefCell::new(Box::new(SparseValueId(k)))),
76 ),
77 Self(v.clone()),
78 )
79 })
80 .collect();
81
82 Box::new(pairs.into_iter()) as Box<dyn Iterator<Item = (Value, Self)>>
83 }
84 _ => return Err(ValueError::CanNotCoerceToIterator),
85 };
86 Ok(result)
87 }
88 #[must_use]
89 pub fn downcast_rust_mut<T: RustType + 'static>(&self) -> Option<Rc<RefCell<Box<T>>>> {
90 match &*self.0.borrow() {
91 Value::RustValue(_rust_type_ref, rc) => {
92 let type_matches = {
93 let guard = rc.borrow();
94 (**guard).as_any().is::<T>()
95 };
96
97 if type_matches {
98 Some(unsafe { std::mem::transmute(rc.clone()) })
99 } else {
100 None
101 }
102 }
103 _ => None,
104 }
105 }
106
107 #[must_use]
108 pub fn unref(&self) -> Ref<Value> {
109 self.0.borrow()
110 }
111
112 #[must_use]
113 pub fn convert_to_string_if_needed(&self) -> String {
114 self.0.borrow().convert_to_string_if_needed()
115 }
116}
117
118impl PartialEq<Self> for ValueReference {
119 fn eq(&self, other: &Self) -> bool {
120 self.0.borrow().eq(&*other.0.borrow())
121 }
122}
123
124impl Eq for ValueReference {}
125
126impl Hash for ValueReference {
127 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
128 self.0.borrow().hash(state);
129 }
130}
131
132impl Display for ValueReference {
133 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
134 write!(f, "{}", self.0.borrow())
135 }
136}