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