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
107
108
109
110
111
112
113
114
115
116
117
118
119
use rkyv::{Archive, Deserialize, Serialize};
use std::{str::FromStr, sync::Arc};

use crate::json::JsonValue;

#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[archive(compare(PartialEq))]
#[archive_attr(derive(Debug))]
pub enum Operator {
    Equal,
    NotEqual,
    Greater,
    GreaterOrEqual,
    Lower,
    LowerOrEqual,
    And,
    Or,
}

impl FromStr for Operator {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "==" => Ok(Operator::Equal),
            "!=" => Ok(Operator::NotEqual),
            ">" => Ok(Operator::Greater),
            ">=" => Ok(Operator::GreaterOrEqual),
            "<" => Ok(Operator::Lower),
            "<=" => Ok(Operator::LowerOrEqual),
            "&&" => Ok(Operator::And),
            "||" => Ok(Operator::Or),
            _ => Err(format!("Invalid operator '{s}'")),
        }
    }
}

#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[archive(
    bound(
        serialize = "__S: rkyv::ser::ScratchSpace + rkyv::ser::SharedSerializeRegistry + rkyv::ser::Serializer",
        deserialize = "__D: rkyv::de::SharedDeserializeRegistry"
    ),
    compare(PartialEq)
)]
#[archive_attr(derive(Debug))]
pub struct BinaryExpression {
    pub operator: Operator,
    #[omit_bounds]
    pub left: Box<JsepNode>,
    #[omit_bounds]
    pub right: Box<JsepNode>,
}

#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[archive(compare(PartialEq))]
#[archive_attr(derive(Debug))]
pub struct ExpressionIdentifier {
    pub name: Arc<str>,
}

#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[archive(compare(PartialEq))]
#[archive_attr(derive(Debug))]
pub struct ExpressionLiteral {
    pub value: JsonValue,
}

#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[archive(
    bound(
        serialize = "__S: rkyv::ser::ScratchSpace + rkyv::ser::SharedSerializeRegistry + rkyv::ser::Serializer",
        deserialize = "__D: rkyv::de::SharedDeserializeRegistry"
    ),
    compare(PartialEq)
)]
#[archive_attr(derive(Debug))]
pub struct ConditionalExpression {
    #[omit_bounds]
    pub test: Box<JsepNode>,
    #[omit_bounds]
    pub consequent: Box<JsepNode>,
    #[omit_bounds]
    pub alternate: Box<JsepNode>,
}

#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[archive(
    bound(
        serialize = "__S: rkyv::ser::ScratchSpace + rkyv::ser::SharedSerializeRegistry + rkyv::ser::Serializer",
        deserialize = "__D: rkyv::de::SharedDeserializeRegistry"
    ),
    compare(PartialEq)
)]
#[archive_attr(derive(Debug))]
pub struct MemberExpression {
    pub computed: bool,
    pub optional: bool,
    #[omit_bounds]
    pub object: Box<JsepNode>,
    #[omit_bounds]
    pub property: Box<JsepNode>,
}

#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[archive(
    bound(
        serialize = "__S: rkyv::ser::ScratchSpace + rkyv::ser::SharedSerializeRegistry + rkyv::ser::Serializer",
        deserialize = "__D: rkyv::de::SharedDeserializeRegistry"
    ),
    compare(PartialEq)
)]
#[archive_attr(derive(Debug))]
pub enum JsepNode {
    ConditionalExpression(ConditionalExpression),
    BinaryExpression(BinaryExpression),
    Identifier(ExpressionIdentifier),
    Literal(ExpressionLiteral),
    MemberExpression(MemberExpression),
}