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
78
79
80
81
82
83
84
85
use std::{rc::Rc, cell::RefCell, mem};
use crate::RantValue;
#[derive(Debug)]
pub enum RantVar {
ByVal(RantValue),
ByRef(Rc<RefCell<RantValue>>)
}
impl Default for RantVar {
fn default() -> Self {
RantVar::ByVal(RantValue::Empty)
}
}
impl Clone for RantVar {
fn clone(&self) -> Self {
match self {
RantVar::ByVal(val) => RantVar::ByVal(val.clone()),
RantVar::ByRef(val_ref) => RantVar::ByRef(Rc::clone(val_ref)),
}
}
}
impl RantVar {
#[inline]
pub fn cloned(&self) -> Self {
match self {
RantVar::ByVal(val) => RantVar::ByVal(val.clone()),
RantVar::ByRef(val_ref) => RantVar::ByRef(Rc::new(RefCell::new(val_ref.borrow().clone()))),
}
}
#[inline]
pub fn is_by_val(&self) -> bool {
matches!(self, RantVar::ByVal(_))
}
#[inline]
pub fn is_by_ref(&self) -> bool {
matches!(self, RantVar::ByRef(_))
}
#[inline]
pub fn make_by_ref(&mut self) {
if self.is_by_ref() { return }
if let RantVar::ByVal(val) = mem::take(self) {
*self = RantVar::ByRef(Rc::new(RefCell::new(val)));
}
}
#[inline]
pub fn write(&mut self, value: RantValue) {
match self {
RantVar::ByVal(val) => *val = value,
RantVar::ByRef(val_ref) => {
val_ref.replace(value);
},
}
}
#[inline]
pub fn value_cloned(&self) -> RantValue {
match self {
RantVar::ByVal(val) => val.clone(),
RantVar::ByRef(val_ref) => val_ref.borrow().clone(),
}
}
}