swamp_script_eval/
value_ref.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use 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 id_type_ref = sparse_map.borrow().rust_type_ref_for_id.clone();
37
38                        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                // Clone each Rc<RefCell<Value>> and collect into a Vec
51                let cloned_rc: Vec<ValueRef> = seq_map.values().cloned().collect();
52
53                // Box the iterator from the Vec
54                Box::new(cloned_rc.into_iter()) as Box<dyn Iterator<Item = ValueRef> + 'static>
55            }
56
57            /*
58                        Self::Array(_, values) => Ok(Box::new(values.into_iter())),
59            Self::Map(_, seq_map) => Ok(Box::new(seq_map.into_values())),
60             */
61            _ => {
62                info!(?inner, "not sure what this is:");
63                todo!()
64            }
65        };
66        Ok(result)
67    }
68
69    /// # Errors
70    ///
71    /// # Panics
72    ///
73    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}