swamp_script_eval/
value_both.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 crate::prelude::ValueReference;
6use std::cell::RefCell;
7use std::rc::Rc;
8use swamp_script_core::prelude::{Value, ValueError};
9use swamp_script_core::value::RustType;
10
11#[derive(Debug, Clone)]
12pub enum VariableValue {
13    Value(Value),
14    Reference(ValueReference),
15}
16
17impl VariableValue {
18    pub(crate) fn to_value(&self) -> Value {
19        match self {
20            Self::Value(v) => v.clone(),
21            Self::Reference(value_ref) => value_ref.0.borrow().clone(),
22        }
23    }
24}
25
26impl PartialEq for VariableValue {
27    fn eq(&self, other: &Self) -> bool {
28        match (self, other) {
29            (Self::Reference(r1), Self::Value(other)) => r1.0.borrow().eq(other),
30            (Self::Value(other), Self::Reference(r2)) => other.eq(&*r2.0.borrow()),
31            (Self::Value(v1), Self::Value(v2)) => v1 == v2,
32            (Self::Reference(r1), Self::Reference(r2)) => r1.0.borrow().eq(&*r2.0.borrow()),
33        }
34    }
35}
36
37impl VariableValue {
38    #[must_use]
39    pub fn downcast_rust_mut_or_not<T: RustType + 'static>(&self) -> Option<Rc<RefCell<Box<T>>>> {
40        match self {
41            VariableValue::Value(v) => v.downcast_rust(),
42            VariableValue::Reference(r) => r.downcast_rust_mut(),
43        }
44    }
45
46    #[must_use]
47    pub fn convert_to_string_if_needed(&self) -> String {
48        match self {
49            Self::Value(v) => v.convert_to_string_if_needed(),
50            Self::Reference(r) => r.convert_to_string_if_needed(),
51        }
52    }
53
54    /// # Errors
55    ///
56    pub fn into_iter(self) -> Result<Box<dyn Iterator<Item = Value>>, ValueError> {
57        match self {
58            Self::Value(v) => v.into_iter(),
59            Self::Reference(_r) => Err(ValueError::CanNotCoerceToIterator),
60        }
61    }
62
63    /// # Errors
64    ///
65    pub fn into_iter_pairs(self) -> Result<Box<dyn Iterator<Item = (Value, Value)>>, ValueError> {
66        match self {
67            Self::Value(v) => v.into_iter_pairs(),
68            Self::Reference(_r) => Err(ValueError::CanNotCoerceToIterator),
69        }
70    }
71
72    /// # Errors
73    ///
74    pub fn into_iter_pairs_mut(
75        self,
76    ) -> Result<Box<dyn Iterator<Item = (Value, ValueReference)>>, ValueError> {
77        match self {
78            Self::Value(_v) => Err(ValueError::CanNotCoerceToIterator),
79            Self::Reference(r) => r.into_iter_mut_pairs(),
80        }
81    }
82}
83
84#[inline]
85#[must_use]
86pub fn convert_to_values(mem_values: &[VariableValue]) -> Option<Vec<Value>> {
87    mem_values
88        .iter()
89        .map(|e| match e {
90            VariableValue::Value(v) => Some(v.clone()),
91            VariableValue::Reference(v) => Some(v.0.borrow().clone()),
92        })
93        .collect()
94}