-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathcontext.rs
More file actions
106 lines (89 loc) · 2.77 KB
/
context.rs
File metadata and controls
106 lines (89 loc) · 2.77 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::define::Result;
use crate::function::InnerFunction;
use crate::value::Value;
use core::clone::Clone;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub enum ContextValue {
Variable(Value),
Function(Arc<InnerFunction>),
}
pub struct Context(pub Arc<Mutex<HashMap<String, ContextValue>>>);
impl Context {
pub fn new() -> Self {
Context(Arc::new(Mutex::new(HashMap::new())))
}
pub fn set_func(&mut self, name: &str, func: Arc<InnerFunction>) {
self.set(name, ContextValue::Function(func.clone()));
}
pub fn set_variable(&mut self, name: &str, value: Value) {
self.set(name, ContextValue::Variable(value));
}
pub fn set(&mut self, name: &str, v: ContextValue) {
self.0.lock().unwrap().insert(name.to_string(), v);
}
pub fn get_func(&self, name: &str) -> Option<Arc<InnerFunction>> {
let value = self.get(name)?;
match value {
ContextValue::Function(func) => Some(func),
ContextValue::Variable(_) => None,
}
}
pub fn get_variable(&self, name: &str) -> Option<Value> {
let value = self.get(name)?;
match value {
ContextValue::Variable(v) => Some(v),
ContextValue::Function(_) => None,
}
}
pub fn get(&self, name: &str) -> Option<ContextValue> {
let binding = self.0.lock().unwrap();
binding.get(name).cloned()
}
pub fn value(&self, name: &str) -> Result<Value> {
let value = {
let binding = self.0.lock().unwrap();
binding.get(name).cloned()
};
match value {
Some(ContextValue::Variable(v)) => Ok(v),
Some(ContextValue::Function(func)) => func(Vec::new()),
None => Ok(Value::None),
}
}
}
///
///```rust
/// use expression_engine::create_context;
/// use expression_engine::Value;
/// let a = create_context!("d" => 3.5, "c" => Arc::new(|params| {
/// Ok(Value::from(3))
/// }));
///```
///
///
#[macro_export]
macro_rules! create_context {
(($ctx:expr) $k:expr => Arc::new($($v:tt)*), $($tt:tt)*) => {{
$ctx.set_func($k, Arc::new($($v)*));
$crate::create_context!(($ctx) $($tt)*);
}};
(($ctx:expr) $k:expr => $v:expr, $($tt:tt)*) => {{
$ctx.set_variable($k, Value::from($v));
$crate::create_context!(($ctx) $($tt)*);
}};
(($ctx:expr) $k:expr => Arc::new($($v:tt)*)) => {{
$ctx.set_func($k, Arc::new($($v)*));
}};
(($ctx:expr) $k:expr => $v:expr) => {{
$ctx.set_variable($k, Value::from($v));
}};
(($ctx:expr)) => {};
($($tt:tt)*) => {{
use std::sync::Arc;
let mut ctx = $crate::Context::new();
$crate::create_context!((&mut ctx) $($tt)*);
ctx
}};
}