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 */
5
6use 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 id_type_ref = sparse_map.borrow().rust_type_ref_for_id.clone();
38
39                        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                // Clone each Rc<RefCell<Value>> and collect into a Vec
52                let cloned_rc: Vec<ValueRef> = seq_map.values().cloned().collect();
53
54                // Box the iterator from the Vec
55                Box::new(cloned_rc.into_iter()) as Box<dyn Iterator<Item = ValueRef> + 'static>
56            }
57
58            /*
59                        Self::Array(_, values) => Ok(Box::new(values.into_iter())),
60            Self::Map(_, seq_map) => Ok(Box::new(seq_map.into_values())),
61             */
62            _ => {
63                info!(?inner, "not sure what this is:");
64                todo!()
65            }
66        };
67        Ok(result)
68    }
69
70    /// # Errors
71    ///
72    /// # Panics
73    ///
74    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}