swamp_script_eval/
value_both.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 */

use crate::prelude::ValueReference;
use std::cell::RefCell;
use std::rc::Rc;
use swamp_script_core::prelude::{Value, ValueError};
use swamp_script_core::value::RustType;

#[derive(Debug, Clone)]
pub enum VariableValue {
    Value(Value),
    Reference(ValueReference),
}

impl PartialEq for VariableValue {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Self::Reference(r1), Self::Value(other)) => r1.0.borrow().eq(other),
            (Self::Value(other), Self::Reference(r2)) => other.eq(&*r2.0.borrow()),
            (Self::Value(v1), Self::Value(v2)) => v1 == v2,
            (Self::Reference(r1), Self::Reference(r2)) => r1.0.borrow().eq(&*r2.0.borrow()),
        }
    }
}

impl VariableValue {
    pub fn downcast_rust_mut_or_not<T: RustType + 'static>(&self) -> Option<Rc<RefCell<Box<T>>>> {
        match self {
            VariableValue::Value(v) => v.downcast_rust(),
            VariableValue::Reference(r) => r.downcast_rust_mut(),
        }
    }

    pub fn convert_to_string_if_needed(&self) -> String {
        match self {
            Self::Value(v) => v.convert_to_string_if_needed(),
            Self::Reference(r) => r.convert_to_string_if_needed(),
        }
    }

    pub fn into_iter(self) -> Result<Box<dyn Iterator<Item = Value>>, ValueError> {
        match self {
            Self::Value(v) => v.into_iter(),
            Self::Reference(_r) => Err(ValueError::CanNotCoerceToIterator),
        }
    }

    pub fn into_iter_pairs(self) -> Result<Box<dyn Iterator<Item = (Value, Value)>>, ValueError> {
        match self {
            Self::Value(v) => v.into_iter_pairs(),
            Self::Reference(_r) => Err(ValueError::CanNotCoerceToIterator),
        }
    }

    pub fn into_iter_pairs_mut(
        self,
    ) -> Result<Box<dyn Iterator<Item = (Value, ValueReference)>>, ValueError> {
        match self {
            Self::Value(_v) => Err(ValueError::CanNotCoerceToIterator),
            Self::Reference(r) => r.into_iter_mut_pairs(),
        }
    }
}

#[inline]
pub fn convert_to_values(mem_values: &[VariableValue]) -> Option<Vec<Value>> {
    mem_values
        .iter()
        .map(|e| match e {
            VariableValue::Value(v) => Some(v.clone()),
            VariableValue::Reference(v) => Some(v.0.borrow().clone()),
        })
        .collect()
}