hurl/jsonpath/
ast.rs

1/*
2 * Hurl (https://hurl.dev)
3 * Copyright (C) 2025 Orange
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *          http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18// https://cburgmer.github.io/json-path-comparison/
19// https://goessner.net/articles/JsonPath/
20// https://jsonpath.com/
21
22#[derive(Clone, Debug, PartialEq, Eq)]
23pub struct Query {
24    pub selectors: Vec<Selector>,
25}
26
27#[derive(Clone, Debug, PartialEq, Eq)]
28pub enum Selector {
29    Wildcard,
30    NameChild(String),
31    ArrayIndex(i64),        // one unique index - can be negative
32    ArrayIndices(Vec<i64>), // two or more indexes (separated by comma) - can be negative
33    ArraySlice(Slice),
34    ArrayWildcard,
35    Filter(Predicate),
36    RecursiveWildcard,
37    RecursiveKey(String),
38}
39
40// For the time-being
41// use simple slice start:end (without the step)
42#[derive(Clone, Debug, PartialEq, Eq)]
43pub struct Slice {
44    pub start: Option<i64>,
45    pub end: Option<i64>,
46}
47
48#[derive(Clone, Debug, PartialEq, Eq)]
49pub struct Predicate {
50    pub key: Vec<String>,
51    pub func: PredicateFunc,
52}
53
54#[derive(Clone, Debug, PartialEq, Eq)]
55pub enum PredicateFunc {
56    KeyExist,
57    EqualBool(bool),
58    EqualString(String),
59    NotEqualString(String),
60    Equal(Number),
61    NotEqual(Number),
62    GreaterThan(Number),
63    GreaterThanOrEqual(Number),
64    LessThan(Number),
65    LessThanOrEqual(Number),
66}
67
68// Number
69// - without rounding
70// - Equalable
71#[derive(Clone, Debug, PartialEq, Eq)]
72pub struct Number {
73    pub int: i64,
74    pub decimal: u64,
75}
76
77impl Number {
78    pub fn to_f64(&self) -> f64 {
79        self.int as f64 + self.decimal as f64 / 1_000_000_000_000_000_000.0
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    pub fn test_number() {
89        assert!((Number { int: 1, decimal: 0 }.to_f64() - 1.0).abs() < 0.0000001);
90    }
91}