1use crate::value::{Value};
2
3pub type CtxAppFn = fn(&dyn Context,&str,Value) -> Option<Value>;
4
5pub const NOEXTRA: u16 = 0;
9pub const JUSTONE: u16 = 1;
10pub const JUSTTWO: u16 = 2;
11pub const TAKEALL: u16 = 3;
12
13
14#[derive(Clone)]
15pub struct CtxApplicative {
16 pub name: String,
17 pub extra: u16,
18 pub f: CtxAppFn,
19}
20
21impl CtxApplicative {
22 pub fn new<N: AsRef<str> + std::fmt::Display>(name: N, e: u16, f: CtxAppFn) -> Self {
23 Self {
24 name: name.as_ref().to_string(),
25 extra: e,
26 f: f,
27 }
28 }
29}
30
31
32pub trait Context {
33 fn new() -> Self where Self: Sized;
34 fn resolve(&self, name: &str) -> Option<CtxApplicative>;
35 fn get_association(&self, name: &str) -> Option<Value>;
36 fn register(&mut self, name: &str, f: CtxApplicative) -> bool;
37 fn register_association(&mut self, name: &str, v: Value) -> bool;
38 fn eval(&mut self, a: Option<CtxApplicative>, v: Value) -> Option<Value>;
39}
40
41pub struct NullContext {}
42
43impl Context for NullContext {
44 fn new() -> NullContext {
45 Self {
46
47 }
48 }
49 fn resolve(&self, _name: &str) -> Option<CtxApplicative> {
50 fn none_fn(_ctx: &dyn Context, _name: &str, _value: Value) -> Option<Value> {
51 None
52 }
53 Some(CtxApplicative::new("none_fn", NOEXTRA, none_fn))
54 }
55 fn get_association(&self, _name: &str) -> Option<Value> {
56 None
57 }
58 fn register(&mut self, _name: &str, _f: CtxApplicative) -> bool {
59 true
60 }
61 fn register_association(&mut self, _name: &str, _v: Value) -> bool {
62 true
63 }
64 fn eval(&mut self, _a: Option<CtxApplicative>, _v: Value) -> Option<Value> {
65 None
66 }
67}
68
69
70pub fn context(mut ctx: impl Context, value: Value) -> Option<Value> {
71 ctx.eval(None, value)
72}