1use std::collections::HashMap;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
12pub struct Span {
13 pub start: usize,
14 pub end: usize,
15 pub line: u32,
16 pub column: u32,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum Version {
22 V1,
23 V2,
24}
25
26#[derive(Debug, Clone, PartialEq)]
27pub struct Ruleset {
28 pub version: Version,
29 pub file_name: Option<String>,
31 pub functions: Vec<Function>,
33 pub services: Vec<Service>,
34 pub parens: HashMap<(usize, usize), Vec<Span>>,
38}
39
40impl Ruleset {
41 pub fn service(&self, name: &str) -> Option<&Service> {
43 self.services.iter().find(|s| s.name == name)
44 }
45}
46
47#[derive(Debug, Clone, PartialEq)]
48pub struct Service {
49 pub name: String,
51 pub name_span: Span,
52 pub body: Body,
53 pub span: Span,
54}
55
56#[derive(Debug, Clone, PartialEq, Default)]
58pub struct Body {
59 pub functions: Vec<Function>,
60 pub matches: Vec<Match>,
61 pub allows: Vec<Allow>,
62}
63
64#[derive(Debug, Clone, PartialEq)]
66pub struct Match {
67 pub path: Vec<Segment>,
68 pub body: Body,
69 pub span: Span,
71}
72
73#[derive(Debug, Clone, PartialEq)]
74pub struct Segment {
75 pub kind: SegmentKind,
76 pub span: Span,
78 pub name_span: Span,
80}
81
82#[derive(Debug, Clone, PartialEq, Eq)]
83pub enum SegmentKind {
84 Literal(String),
86 Wildcard(String),
88 Recursive(String),
90}
91
92impl SegmentKind {
93 pub fn variable(&self) -> Option<&str> {
95 match self {
96 Self::Literal(_) => None,
97 Self::Wildcard(name) | Self::Recursive(name) => Some(name),
98 }
99 }
100}
101
102#[derive(Debug, Clone, PartialEq)]
104pub struct Allow {
105 pub methods: Vec<MethodName>,
106 pub condition: Option<Expr>,
108 pub span: Span,
110}
111
112#[derive(Debug, Clone, PartialEq)]
113pub struct MethodName {
114 pub name: String,
115 pub method: Option<Method>,
117 pub span: Span,
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq)]
121pub enum Method {
122 Read,
123 Write,
124 Get,
125 List,
126 Create,
127 Update,
128 Delete,
129}
130
131impl Method {
132 pub fn from_name(name: &str) -> Option<Self> {
133 Some(match name {
134 "read" => Self::Read,
135 "write" => Self::Write,
136 "get" => Self::Get,
137 "list" => Self::List,
138 "create" => Self::Create,
139 "update" => Self::Update,
140 "delete" => Self::Delete,
141 _ => return None,
142 })
143 }
144
145 pub fn covers(self, request: Self) -> bool {
147 self == request
148 || matches!(
149 (self, request),
150 (Self::Read, Self::Get | Self::List)
151 | (Self::Write, Self::Create | Self::Update | Self::Delete)
152 )
153 }
154}
155
156#[derive(Debug, Clone, PartialEq)]
158pub struct Function {
159 pub name: Ident,
160 pub params: Vec<Ident>,
161 pub lets: Vec<Let>,
162 pub result: Expr,
163 pub span: Span,
165}
166
167#[derive(Debug, Clone, PartialEq)]
168pub struct Let {
169 pub name: Ident,
170 pub value: Expr,
171 pub span: Span,
173}
174
175#[derive(Debug, Clone, PartialEq, Eq)]
176pub struct Ident {
177 pub name: String,
178 pub span: Span,
179}
180
181#[derive(Debug, Clone, PartialEq)]
182pub struct Expr {
183 pub kind: ExprKind,
184 pub span: Span,
186}
187
188#[derive(Debug, Clone, PartialEq)]
189pub enum ExprKind {
190 Null,
191 Bool(bool),
192 Int(i64),
193 IntOverflow(String),
195 Float(f64),
196 String(String),
197 Bytes(Vec<u8>),
198 Ident(String),
200 List(Vec<Expr>),
201 Map(Vec<(Expr, Expr)>),
203 Path(Vec<PathPart>),
205 Member {
207 object: Box<Expr>,
208 field: Ident,
209 },
210 Index {
212 object: Box<Expr>,
213 index: Box<Expr>,
214 },
215 Slice {
217 object: Box<Expr>,
218 start: Box<Expr>,
219 end: Box<Expr>,
220 },
221 Call {
223 callee: Callee,
224 args: Vec<Expr>,
225 },
226 Unary {
227 op: UnaryOp,
228 operand: Box<Expr>,
229 },
230 Binary {
231 op: BinaryOp,
232 op_span: Span,
234 left: Box<Expr>,
235 right: Box<Expr>,
236 },
237 Is {
239 value: Box<Expr>,
240 keyword: Span,
242 type_name: Ident,
243 },
244 Ternary {
246 condition: Box<Expr>,
247 question: Span,
249 then: Box<Expr>,
250 otherwise: Box<Expr>,
251 },
252}
253
254#[derive(Debug, Clone, PartialEq)]
255pub enum Callee {
256 Global(Ident),
258 Namespaced { namespace: Ident, name: Ident },
260 Method { receiver: Box<Expr>, name: Ident },
262}
263
264#[derive(Debug, Clone, PartialEq)]
265pub enum PathPart {
266 Segment(String),
268 Expr(Expr),
270}
271
272#[derive(Debug, Clone, Copy, PartialEq, Eq)]
273pub enum UnaryOp {
274 Not,
275 Neg,
276}
277
278#[derive(Debug, Clone, Copy, PartialEq, Eq)]
279pub enum BinaryOp {
280 Or,
281 And,
282 Eq,
283 Ne,
284 Lt,
285 Le,
286 Gt,
287 Ge,
288 In,
289 Add,
290 Sub,
291 Mul,
292 Div,
293 Mod,
294}