Skip to main content

httpql/
primitives.rs

1use core::fmt;
2
3#[derive(Clone, Debug, Default)]
4pub struct Query {
5    pub preset: Option<ExprPreset>,
6    pub source: Option<ExprSource>,
7    pub row: Option<ClauseRow>,
8    pub request: Option<ClauseRequest>,
9    pub response: Option<ClauseResponse>,
10    pub and: Option<(Box<Query>, Box<Query>)>,
11    pub or: Option<(Box<Query>, Box<Query>)>,
12}
13
14impl fmt::Display for Query {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        if let Some(expr) = &self.preset {
17            return write!(f, "{}", expr);
18        }
19        if let Some(expr) = &self.source {
20            return write!(f, "{}", expr);
21        }
22        if let Some(expr) = &self.row {
23            return write!(f, "row.{}", expr);
24        }
25        if let Some(expr) = &self.request {
26            return write!(f, "req.{}", expr);
27        }
28        if let Some(expr) = &self.response {
29            return write!(f, "resp.{}", expr);
30        }
31        if let Some(expr) = &self.and {
32            return write!(f, "({} and {})", expr.0, expr.1);
33        }
34        if let Some(expr) = &self.or {
35            return write!(f, "({} or {})", expr.0, expr.1);
36        }
37        write!(f, "()")
38    }
39}
40
41#[derive(Clone, Debug, Default)]
42pub struct ClauseRow {
43    pub id: Option<ExprInt>,
44}
45
46impl fmt::Display for ClauseRow {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        if let Some(expr) = &self.id {
49            return write!(f, "id.{}", expr);
50        }
51        Ok(())
52    }
53}
54
55#[derive(Clone, Debug, Default)]
56pub struct ClauseHeader {
57    pub name: Option<ExprString>,
58    pub value: Option<ExprString>,
59}
60
61impl fmt::Display for ClauseHeader {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        match (&self.name, &self.value) {
64            (Some(name), Some(value))
65                if matches!(name.operator, OperatorString::Eq) && !name.is_raw =>
66            {
67                write!(f, "[\"{}\"].{}", name.value, value)
68            }
69            (Some(name), None) => {
70                write!(f, ".name.{}", name)
71            }
72            (None, Some(value)) => {
73                write!(f, ".value.{}", value)
74            }
75            _ => Err(fmt::Error),
76        }
77    }
78}
79
80#[derive(Clone, Debug, Default)]
81pub struct ClauseResponse {
82    pub body: Option<ExprString>,
83    pub header: Option<ClauseHeader>,
84    pub length: Option<ExprInt>,
85    pub roundtrip_time: Option<ExprInt>,
86    pub raw: Option<ExprString>,
87    pub status_code: Option<ExprInt>,
88}
89
90impl fmt::Display for ClauseResponse {
91    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92        if let Some(expr) = &self.body {
93            return write!(f, "body.{}", expr);
94        }
95        if let Some(expr) = &self.header {
96            return write!(f, "header{}", expr);
97        }
98        if let Some(expr) = &self.length {
99            return write!(f, "len.{}", expr);
100        }
101        if let Some(expr) = &self.raw {
102            return write!(f, "raw.{}", expr);
103        }
104        if let Some(expr) = &self.roundtrip_time {
105            return write!(f, "roundtrip.{}", expr);
106        }
107        if let Some(expr) = &self.status_code {
108            return write!(f, "code.{}", expr);
109        }
110        Err(fmt::Error)
111    }
112}
113
114#[derive(Clone, Debug, Default)]
115pub struct ClauseRequest {
116    pub body: Option<ExprString>,
117    pub created_at: Option<ExprDate>,
118    pub file_extension: Option<ExprString>,
119    pub header: Option<ClauseHeader>,
120    pub host: Option<ExprString>,
121    pub is_tls: Option<ExprBool>,
122    pub length: Option<ExprInt>,
123    pub method: Option<ExprString>,
124    pub path: Option<ExprString>,
125    pub port: Option<ExprInt>,
126    pub query: Option<ExprString>,
127    pub raw: Option<ExprString>,
128}
129
130impl fmt::Display for ClauseRequest {
131    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132        if let Some(expr) = &self.body {
133            return write!(f, "body.{}", expr);
134        }
135        if let Some(expr) = &self.created_at {
136            return write!(f, "created_at.{}", expr);
137        }
138        if let Some(expr) = &self.file_extension {
139            return write!(f, "ext.{}", expr);
140        }
141        if let Some(expr) = &self.header {
142            return write!(f, "header{}", expr);
143        }
144        if let Some(expr) = &self.host {
145            return write!(f, "host.{}", expr);
146        }
147        if let Some(expr) = &self.is_tls {
148            return write!(f, "tls.{}", expr);
149        }
150        if let Some(expr) = &self.length {
151            return write!(f, "len.{}", expr);
152        }
153        if let Some(expr) = &self.method {
154            return write!(f, "method.{}", expr);
155        }
156        if let Some(expr) = &self.path {
157            return write!(f, "path.{}", expr);
158        }
159        if let Some(expr) = &self.port {
160            return write!(f, "port.{}", expr);
161        }
162        if let Some(expr) = &self.query {
163            return write!(f, "query.{}", expr);
164        }
165        if let Some(expr) = &self.raw {
166            return write!(f, "raw.{}", expr);
167        }
168        Err(fmt::Error)
169    }
170}
171
172#[derive(Clone, Debug)]
173pub struct ExprString {
174    pub value: String,
175    pub operator: OperatorString,
176    pub is_raw: bool,
177}
178
179impl fmt::Display for ExprString {
180    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181        if self.is_raw {
182            write!(f, r"{}:/{}/", self.operator, self.value)
183        } else {
184            write!(
185                f,
186                "{}:{}",
187                self.operator,
188                serde_json::to_string(self.value.as_str()).expect("Failed to serialize string")
189            )
190        }
191    }
192}
193
194#[derive(Clone, Debug)]
195pub enum OperatorString {
196    Eq,
197    Ne,
198    Cont,
199    Ncont,
200    Like,
201    Nlike,
202    Regex,
203    Nregex,
204}
205
206impl fmt::Display for OperatorString {
207    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208        match self {
209            OperatorString::Eq => write!(f, "eq"),
210            OperatorString::Ne => write!(f, "ne"),
211            OperatorString::Cont => write!(f, "cont"),
212            OperatorString::Ncont => write!(f, "ncont"),
213            OperatorString::Like => write!(f, "like"),
214            OperatorString::Nlike => write!(f, "nlike"),
215            OperatorString::Regex => write!(f, "regex"),
216            OperatorString::Nregex => write!(f, "nregex"),
217        }
218    }
219}
220
221#[derive(Clone, Debug)]
222pub struct ExprInt {
223    pub value: i32,
224    pub operator: OperatorInt,
225}
226
227impl fmt::Display for ExprInt {
228    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229        write!(f, "{}:{}", self.operator, self.value)
230    }
231}
232
233#[derive(Clone, Debug)]
234pub enum OperatorInt {
235    Lt,
236    Lte,
237    Gt,
238    Gte,
239    Eq,
240    Ne,
241}
242
243impl fmt::Display for OperatorInt {
244    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245        match self {
246            OperatorInt::Lt => write!(f, "lt"),
247            OperatorInt::Lte => write!(f, "lte"),
248            OperatorInt::Gt => write!(f, "gt"),
249            OperatorInt::Gte => write!(f, "gte"),
250            OperatorInt::Eq => write!(f, "eq"),
251            OperatorInt::Ne => write!(f, "ne"),
252        }
253    }
254}
255
256#[derive(Clone, Debug)]
257pub struct ExprDate {
258    pub value: String,
259    pub operator: OperatorDate,
260}
261
262impl fmt::Display for ExprDate {
263    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
264        write!(f, "{}:\"{}\"", self.operator, self.value)
265    }
266}
267
268#[derive(Clone, Debug)]
269pub enum OperatorDate {
270    Lt,
271    Gt,
272}
273
274impl fmt::Display for OperatorDate {
275    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276        match self {
277            OperatorDate::Lt => write!(f, "lt"),
278            OperatorDate::Gt => write!(f, "gt"),
279        }
280    }
281}
282
283#[derive(Clone, Debug)]
284pub struct ExprBool {
285    pub value: bool,
286    pub operator: OperatorBool,
287}
288
289impl fmt::Display for ExprBool {
290    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
291        write!(f, "{}:{}", self.operator, self.value)
292    }
293}
294
295#[derive(Clone, Debug)]
296pub enum OperatorBool {
297    Eq,
298    Ne,
299}
300
301impl fmt::Display for OperatorBool {
302    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
303        match self {
304            OperatorBool::Eq => write!(f, "eq"),
305            OperatorBool::Ne => write!(f, "ne"),
306        }
307    }
308}
309
310#[derive(Clone, Debug)]
311pub enum ExprPreset {
312    Name(String),
313    Alias(String),
314}
315
316impl fmt::Display for ExprPreset {
317    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318        match self {
319            ExprPreset::Name(name) => write!(f, "preset:\"{}\"", name),
320            ExprPreset::Alias(alias) => write!(f, "preset:{}", alias),
321        }
322    }
323}
324
325#[derive(Clone, Debug)]
326pub struct ExprSource {
327    pub name: String,
328}
329
330impl fmt::Display for ExprSource {
331    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332        write!(f, "source:\"{}\"", self.name)
333    }
334}