• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

getdozer / dozer / 5609194599

pending completion
5609194599

push

github

web-flow
fix: Fix target url from cli args usage (#1774)

42569 of 55270 relevant lines covered (77.02%)

31833.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

47.31
/dozer-sql/src/jsonpath/path/top.rs
1
use crate::jsonpath::parser::model::*;
2
use crate::jsonpath::path::JsonPathValue::{NewValue, NoValue, Slice};
3
use crate::jsonpath::path::{json_path_instance, JsonPathValue, Path, PathInstance};
4
use dozer_types::json_types::JsonValue::{Array, Object};
5
use dozer_types::json_types::{serde_json_to_json_value, JsonValue};
6
use dozer_types::serde_json::json;
7

8
/// to process the element [*]
9
pub(crate) struct Wildcard {}
10

11
impl<'a> Path<'a> for Wildcard {
12
    type Data = JsonValue;
13

14
    fn find(&self, data: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
2✔
15
        data.flat_map_slice(|data| {
2✔
16
            let res = match data {
2✔
17
                Array(elems) => {
2✔
18
                    let mut res = vec![];
2✔
19
                    for el in elems.iter() {
4✔
20
                        res.push(Slice(el));
4✔
21
                    }
4✔
22

23
                    res
2✔
24
                }
25
                Object(elems) => {
×
26
                    let mut res = vec![];
×
27
                    for el in elems.values() {
×
28
                        res.push(Slice(el));
×
29
                    }
×
30
                    res
×
31
                }
32
                _ => vec![],
×
33
            };
34
            if res.is_empty() {
2✔
35
                vec![NoValue]
×
36
            } else {
37
                res
2✔
38
            }
39
        })
2✔
40
    }
2✔
41
}
42

43
/// empty path. Returns incoming data.
44
pub(crate) struct IdentityPath {}
45

46
impl<'a> Path<'a> for IdentityPath {
47
    type Data = JsonValue;
48

49
    fn find(&self, data: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
×
50
        vec![data]
×
51
    }
×
52
}
53

54
pub(crate) struct EmptyPath {}
55

56
impl<'a> Path<'a> for EmptyPath {
57
    type Data = JsonValue;
58

59
    fn find(&self, _data: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
×
60
        vec![]
×
61
    }
×
62
}
63

64
/// process $ element
65
pub(crate) struct RootPointer<'a, T> {
66
    root: &'a T,
67
}
68

69
impl<'a, T> RootPointer<'a, T> {
70
    pub(crate) fn new(root: &'a T) -> RootPointer<'a, T> {
29✔
71
        RootPointer { root }
29✔
72
    }
29✔
73
}
74

75
impl<'a> Path<'a> for RootPointer<'a, JsonValue> {
76
    type Data = JsonValue;
77

78
    fn find(&self, _data: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
28✔
79
        vec![Slice(self.root)]
28✔
80
    }
28✔
81
}
82

83
/// process object fields like ['key'] or .key
84
pub(crate) struct ObjectField<'a> {
85
    key: &'a str,
86
}
87

88
impl<'a> ObjectField<'a> {
89
    pub(crate) fn new(key: &'a str) -> ObjectField<'a> {
37✔
90
        ObjectField { key }
37✔
91
    }
37✔
92
}
93

94
impl<'a> Clone for ObjectField<'a> {
95
    fn clone(&self) -> Self {
×
96
        ObjectField::new(self.key)
×
97
    }
×
98
}
99

100
impl<'a> Path<'a> for FnPath {
101
    type Data = JsonValue;
102

103
    fn flat_find(
×
104
        &self,
×
105
        input: Vec<JsonPathValue<'a, Self::Data>>,
×
106
        is_search_length: bool,
×
107
    ) -> Vec<JsonPathValue<'a, Self::Data>> {
×
108
        if JsonPathValue::only_no_value(&input) {
×
109
            return vec![NoValue];
×
110
        }
×
111

112
        let res = if is_search_length {
×
113
            NewValue(
×
114
                serde_json_to_json_value(json!(input.iter().filter(|v| v.has_value()).count()))
×
115
                    .unwrap(),
×
116
            )
×
117
        } else {
118
            let take_len = |v: &JsonValue| match v {
×
119
                Array(elems) => NewValue(serde_json_to_json_value(json!(elems.len())).unwrap()),
×
120
                _ => NoValue,
×
121
            };
×
122

123
            match input.get(0) {
×
124
                Some(v) => match v {
×
125
                    NewValue(d) => take_len(d),
×
126
                    Slice(s) => take_len(s),
×
127
                    NoValue => NoValue,
×
128
                },
129
                None => NoValue,
×
130
            }
131
        };
132
        vec![res]
×
133
    }
×
134

135
    fn needs_all(&self) -> bool {
×
136
        true
×
137
    }
×
138
}
139

140
pub(crate) enum FnPath {
141
    Size,
142
}
143

144
impl<'a> Path<'a> for ObjectField<'a> {
145
    type Data = JsonValue;
146

147
    fn find(&self, data: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
39✔
148
        let take_field = |v: &'a JsonValue| match v {
39✔
149
            Object(fields) => fields.get(self.key),
39✔
150
            _ => None,
×
151
        };
39✔
152

153
        let res = match data {
39✔
154
            Slice(js) => take_field(js).map(Slice).unwrap_or_else(|| NoValue),
39✔
155
            _ => NoValue,
×
156
        };
157
        vec![res]
39✔
158
    }
39✔
159
}
160
/// the top method of the processing ..*
161
pub(crate) struct DescentWildcard;
162

163
impl<'a> Path<'a> for DescentWildcard {
164
    type Data = JsonValue;
165

166
    fn find(&self, data: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
2✔
167
        data.map_slice(deep_flatten)
2✔
168
    }
2✔
169
}
170

171
fn deep_flatten(data: &JsonValue) -> Vec<&JsonValue> {
14✔
172
    let mut acc = vec![];
14✔
173
    match data {
14✔
174
        Object(elems) => {
4✔
175
            for v in elems.values() {
8✔
176
                acc.push(v);
8✔
177
                acc.append(&mut deep_flatten(v));
8✔
178
            }
8✔
179
        }
180
        Array(elems) => {
2✔
181
            for v in elems.iter() {
4✔
182
                acc.push(v);
4✔
183
                acc.append(&mut deep_flatten(v));
4✔
184
            }
4✔
185
        }
186
        _ => (),
8✔
187
    }
188
    acc
14✔
189
}
14✔
190

191
fn deep_path_by_key<'a>(data: &'a JsonValue, key: ObjectField<'a>) -> Vec<&'a JsonValue> {
×
192
    let mut level: Vec<&JsonValue> = JsonPathValue::into_data(key.find(data.into()));
×
193
    match data {
×
194
        Object(elems) => {
×
195
            let mut next_levels: Vec<&JsonValue> = elems
×
196
                .values()
×
197
                .flat_map(|v| deep_path_by_key(v, key.clone()))
×
198
                .collect();
×
199
            level.append(&mut next_levels);
×
200
            level
×
201
        }
202
        Array(elems) => {
×
203
            let mut next_levels: Vec<&JsonValue> = elems
×
204
                .iter()
×
205
                .flat_map(|v| deep_path_by_key(v, key.clone()))
×
206
                .collect();
×
207
            level.append(&mut next_levels);
×
208
            level
×
209
        }
210
        _ => level,
×
211
    }
212
}
×
213

214
/// processes decent object like ..
215
pub(crate) struct DescentObject<'a> {
216
    key: &'a str,
217
}
218

219
impl<'a> Path<'a> for DescentObject<'a> {
220
    type Data = JsonValue;
221

222
    fn find(&self, data: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
×
223
        data.flat_map_slice(|data| {
×
224
            let res_col = deep_path_by_key(data, ObjectField::new(self.key));
×
225
            if res_col.is_empty() {
×
226
                vec![NoValue]
×
227
            } else {
228
                JsonPathValue::map_vec(res_col)
×
229
            }
230
        })
×
231
    }
×
232
}
233

234
impl<'a> DescentObject<'a> {
235
    pub fn new(key: &'a str) -> Self {
×
236
        DescentObject { key }
×
237
    }
×
238
}
239

240
/// the top method of the processing representing the chain of other operators
241
pub(crate) struct Chain<'a> {
242
    chain: Vec<PathInstance<'a>>,
243
    is_search_length: bool,
244
}
245

246
impl<'a> Chain<'a> {
247
    pub fn new(chain: Vec<PathInstance<'a>>, is_search_length: bool) -> Self {
29✔
248
        Chain {
29✔
249
            chain,
29✔
250
            is_search_length,
29✔
251
        }
29✔
252
    }
29✔
253
    pub fn from(chain: &'a [JsonPath], root: &'a JsonValue) -> Self {
29✔
254
        let chain_len = chain.len();
29✔
255
        let is_search_length = if chain_len > 2 {
29✔
256
            let mut res = false;
23✔
257
            // if the result of the slice expected to be a slice, union or filter -
23✔
258
            // length should return length of resulted array
23✔
259
            // In all other cases, including single index, we should fetch item from resulting array
23✔
260
            // and return length of that item
23✔
261
            res = match chain.get(chain_len - 1).expect("chain element disappeared") {
23✔
262
                JsonPath::Fn(Function::Length) => {
263
                    for item in chain.iter() {
×
264
                        match (item, res) {
×
265
                            // if we found union, slice, filter or wildcard - set search to true
266
                            (
267
                                JsonPath::Index(JsonPathIndex::UnionIndex(_))
268
                                | JsonPath::Index(JsonPathIndex::UnionKeys(_))
269
                                | JsonPath::Index(JsonPathIndex::Slice(_, _, _))
270
                                | JsonPath::Index(JsonPathIndex::Filter(_))
271
                                | JsonPath::Wildcard,
272
                                false,
273
                            ) => {
×
274
                                res = true;
×
275
                            }
×
276
                            // if we found a fetching of single index - reset search to false
277
                            (JsonPath::Index(JsonPathIndex::Single(_)), true) => {
×
278
                                res = false;
×
279
                            }
×
280
                            (_, _) => {}
×
281
                        }
282
                    }
283
                    res
×
284
                }
285
                _ => false,
23✔
286
            };
287
            res
23✔
288
        } else {
289
            false
6✔
290
        };
291

292
        Chain::new(
29✔
293
            chain.iter().map(|p| json_path_instance(p, root)).collect(),
82✔
294
            is_search_length,
29✔
295
        )
29✔
296
    }
29✔
297
}
298

299
impl<'a> Path<'a> for Chain<'a> {
300
    type Data = JsonValue;
301

302
    fn find(&self, data: JsonPathValue<'a, Self::Data>) -> Vec<JsonPathValue<'a, Self::Data>> {
29✔
303
        let mut res = vec![data];
29✔
304

305
        for inst in self.chain.iter() {
81✔
306
            if inst.needs_all() {
81✔
307
                res = inst.flat_find(res, self.is_search_length)
×
308
            } else {
309
                res = res.into_iter().flat_map(|d| inst.find(d)).collect()
84✔
310
            }
311
        }
312
        res
29✔
313
    }
29✔
314
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc