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

tremor-rs / tremor-runtime / 2058612730

pending completion
2058612730

Pull #1077

github

GitHub
Merge 08ea76008 into 85f4dfb1e
Pull Request #1077: Connectors Implementation

14162 of 14162 new or added lines in 167 files covered. (100.0%)

24031 of 28363 relevant lines covered (84.73%)

4.25 hits per line

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

64.33
/tremor-value/src/serde/value/de.rs
1
// Copyright 2020-2021, The Tremor Team
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
use crate::{Error, Object, Value};
16
use beef::Cow;
17
use serde::de::{EnumAccess, IntoDeserializer, VariantAccess};
18
use serde_ext::de::{
19
    self, Deserialize, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor,
20
};
21
use serde_ext::forward_to_deserialize_any;
22
use simd_json::StaticNode;
23
use std::fmt;
24

25
impl<'de> de::Deserializer<'de> for Value<'de> {
26
    type Error = Error;
27

28
    // Look at the input data to decide what Serde data model type to
29
    // deserialize as. Not all data formats are able to support this operation.
30
    // Formats that support `deserialize_any` are known as self-describing.
31
    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
62✔
32
    where
33
        V: Visitor<'de>,
34
    {
35
        match self {
62✔
36
            Value::Static(StaticNode::Null) => visitor.visit_unit(),
1✔
37
            Value::Static(StaticNode::Bool(b)) => visitor.visit_bool(b),
6✔
38
            Self::Static(StaticNode::I64(n)) => visitor.visit_i64(n),
14✔
39
            #[cfg(feature = "128bit")]
40
            Self::Static(StaticNode::I128(n)) => visitor.visit_i128(n),
×
41
            Self::Static(StaticNode::U64(n)) => visitor.visit_u64(n),
24✔
42
            #[cfg(feature = "128bit")]
43
            Self::Static(StaticNode::U128(n)) => visitor.visit_u128(n),
×
44
            Value::Static(StaticNode::F64(n)) => visitor.visit_f64(n),
2✔
45
            Value::String(s) => {
36✔
46
                if s.is_borrowed() {
110✔
47
                    visitor.visit_borrowed_str(s.unwrap_borrowed())
6✔
48
                } else {
49
                    visitor.visit_string(s.into_owned())
64✔
50
                }
51
            }
52
            Value::Array(a) => visitor.visit_seq(Array(a.iter())),
8✔
53
            Value::Object(o) => visitor.visit_map(ObjectAccess {
10✔
54
                i: o.iter(),
5✔
55
                v: &Value::Static(StaticNode::Null),
×
56
            }),
57
            Value::Bytes(b) => visitor.visit_bytes(&b),
×
58
        }
59
    }
60

61
    #[cfg_attr(not(feature = "no-inline"), inline)]
62
    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
24✔
63
    where
64
        V: Visitor<'de>,
65
    {
66
        if self == Self::Static(StaticNode::Null) {
48✔
67
            visitor.visit_unit()
×
68
        } else {
69
            visitor.visit_some(self)
48✔
70
        }
71
    }
72

73
    #[cfg_attr(not(feature = "no-inline"), inline)]
74
    fn deserialize_struct<V>(
28✔
75
        self,
76
        _name: &'static str,
77
        _fields: &'static [&'static str],
78
        visitor: V,
79
    ) -> Result<V::Value, Error>
80
    where
81
        V: Visitor<'de>,
82
    {
83
        match self {
28✔
84
            // Give the visitor access to each element of the sequence.
85
            Value::Array(a) => visitor.visit_seq(Array(a.iter())),
×
86
            Value::Object(o) => visitor.visit_map(ObjectAccess {
56✔
87
                i: o.iter(),
28✔
88
                v: &Value::Static(StaticNode::Null),
×
89
            }),
90
            _ => Err(Error::ExpectedMap),
×
91
        }
92
    }
93

94
    #[cfg_attr(not(feature = "no-inline"), inline)]
95
    fn deserialize_enum<V>(
2✔
96
        self,
97
        name: &str,
98
        _variants: &'static [&'static str],
99
        visitor: V,
100
    ) -> Result<V::Value, Error>
101
    where
102
        V: Visitor<'de>,
103
    {
104
        let (variant, value) = match self {
4✔
105
            Value::Object(value) => {
1✔
106
                let mut iter = value.into_iter();
1✔
107
                let (variant, value) = match iter.next() {
3✔
108
                    Some(v) => v,
1✔
109
                    None => {
×
110
                        return Err(Error::Serde(format!(
×
111
                            "Missing enum type for variant in enum `{name}`"
×
112
                        )));
113
                    }
114
                };
115
                // enums are encoded in json as maps with a single key:value pair
116
                if let Some((extra, _)) = iter.next() {
1✔
117
                    return Err(Error::Serde(format!(
×
118
                        "extra values in enum `{name}`: `{variant}` .. `{extra}`"
×
119
                    )));
120
                }
121
                (variant, Some(value))
1✔
122
            }
123
            Value::String(variant) => (variant, None),
1✔
124
            _other => {
×
125
                return Err(Error::Serde("Not a string".to_string()));
×
126
            }
127
        };
128

129
        visitor.visit_enum(EnumDeserializer { variant, value })
2✔
130
    }
131

132
    forward_to_deserialize_any! {
133
        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
134
            bytes byte_buf unit unit_struct newtype_struct seq tuple
135
            tuple_struct map identifier ignored_any
136
    }
137
}
138

139
struct EnumDeserializer<'de> {
140
    variant: Cow<'de, str>,
141
    value: Option<Value<'de>>,
142
}
143

144
impl<'de> EnumAccess<'de> for EnumDeserializer<'de> {
145
    type Error = Error;
146
    type Variant = VariantDeserializer<'de>;
147

148
    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
2✔
149
    where
150
        V: DeserializeSeed<'de>,
151
    {
152
        let variant = self.variant.into_deserializer();
4✔
153
        let visitor = VariantDeserializer { value: self.value };
2✔
154
        seed.deserialize(variant).map(|v| (v, visitor))
6✔
155
    }
156
}
157

158
impl<'de> IntoDeserializer<'de, Error> for Value<'de> {
159
    type Deserializer = Self;
160

161
    fn into_deserializer(self) -> Self::Deserializer {
×
162
        self
×
163
    }
164
}
165

166
struct VariantDeserializer<'de> {
167
    value: Option<Value<'de>>,
168
}
169

170
impl<'de> VariantAccess<'de> for VariantDeserializer<'de> {
171
    type Error = Error;
172

173
    fn unit_variant(self) -> Result<(), Error> {
1✔
174
        match self.value {
1✔
175
            Some(value) => Deserialize::deserialize(value),
×
176
            None => Ok(()),
1✔
177
        }
178
    }
179

180
    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
181
    where
182
        T: DeserializeSeed<'de>,
183
    {
184
        match self.value {
×
185
            Some(value) => seed.deserialize(value),
×
186
            None => Err(Error::Serde("expected newtype variant".to_string()))
×
187
            // None => Err(serde::de::Error::invalid_type(
188
            //     Unexpected::UnitVariant,
189
            //     &"newtype variant",
190
            // )),
191
        }
192
    }
193

194
    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
195
    where
196
        V: Visitor<'de>,
197
    {
198
        match self.value {
×
199
            Some(Value::Array(v)) => {
×
200
                if v.is_empty() {
×
201
                    visitor.visit_unit()
×
202
                } else {
203
                    visitor.visit_seq(Array(v.iter()))
×
204
                }
205
            }
206
            Some(_) | None => Err(Error::Serde("expected tuple variant".to_string())),
×
207
        }
208
    }
209

210
    fn struct_variant<V>(
1✔
211
        self,
212
        _fields: &'static [&'static str],
213
        visitor: V,
214
    ) -> Result<V::Value, Error>
215
    where
216
        V: Visitor<'de>,
217
    {
218
        match self.value {
2✔
219
            Some(Value::Object(v)) => visitor.visit_map(ObjectAccess {
2✔
220
                i: v.iter(),
1✔
221
                v: &Value::Static(StaticNode::Null),
×
222
            }),
223
            Some(_) | None => Err(Error::Serde("expected struct variant".to_string())),
×
224
        }
225
    }
226
}
227

228
struct Array<'de, 'value: 'de>(std::slice::Iter<'de, Value<'value>>);
229

230
// `SeqAccess` is provided to the `Visitor` to give it the ability to iterate
231
// through elements of the sequence.
232
impl<'de, 'value> SeqAccess<'de> for Array<'value, 'de> {
233
    type Error = Error;
234

235
    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
4✔
236
    where
237
        T: DeserializeSeed<'de>,
238
    {
239
        //TODO: This is ugly
240
        self.0
8✔
241
            .next()
242
            .map_or(Ok(None), |v| seed.deserialize(v.clone()).map(Some))
10✔
243
    }
244
}
245

246
struct ObjectAccess<'de, 'value: 'de> {
247
    i: halfbrown::Iter<'de, Cow<'value, str>, Value<'value>>,
248
    v: &'de Value<'value>,
249
}
250

251
// `MapAccess` is provided to the `Visitor` to give it the ability to iterate
252
// through entries of the map.
253
impl<'de, 'value> MapAccess<'de> for ObjectAccess<'value, 'de> {
254
    type Error = Error;
255

256
    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
32✔
257
    where
258
        K: DeserializeSeed<'de>,
259
    {
260
        if let Some((k, v)) = self.i.next() {
63✔
261
            self.v = v;
31✔
262
            seed.deserialize(Value::String(k.clone())).map(Some)
62✔
263
        } else {
264
            Ok(None)
32✔
265
        }
266
    }
267

268
    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
61✔
269
    where
270
        V: DeserializeSeed<'de>,
271
    {
272
        //TODO: This is ugly
273
        seed.deserialize(self.v.clone())
61✔
274
    }
275
}
276

277
impl<'de> Deserialize<'de> for Value<'de> {
278
    fn deserialize<D>(deserializer: D) -> Result<Value<'de>, D::Error>
4✔
279
    where
280
        D: Deserializer<'de>,
281
    {
282
        deserializer.deserialize_any(ValueVisitor)
4✔
283
    }
284
}
285

286
struct ValueVisitor;
287

288
impl<'de> Visitor<'de> for ValueVisitor {
289
    type Value = Value<'de>;
290

291
    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
×
292
        formatter.write_str("an JSONesque value")
×
293
    }
294

295
    /****************** unit ******************/
296
    #[cfg_attr(not(feature = "no-inline"), inline)]
297
    fn visit_unit<E>(self) -> Result<Self::Value, E> {
1✔
298
        Ok(Value::Static(StaticNode::Null))
1✔
299
    }
300

301
    /****************** bool ******************/
302
    #[cfg_attr(not(feature = "no-inline"), inline)]
303
    fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> {
3✔
304
        Ok(Value::Static(StaticNode::Bool(value)))
3✔
305
    }
306

307
    /****************** Option ******************/
308
    #[cfg_attr(not(feature = "no-inline"), inline)]
309
    fn visit_none<E>(self) -> Result<Self::Value, E> {
×
310
        Ok(Value::Static(StaticNode::Null))
×
311
    }
312

313
    #[cfg_attr(not(feature = "no-inline"), inline)]
314
    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
315
    where
316
        D: Deserializer<'de>,
317
    {
318
        deserializer.deserialize_any(self)
×
319
    }
320

321
    /****************** enum ******************/
322
    /*
323
    fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error> where
324
        A: EnumAccess<'de>,
325
    {
326
    }
327
     */
328

329
    /****************** i64 ******************/
330
    #[cfg_attr(not(feature = "no-inline"), inline)]
331
    fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
×
332
    where
333
        E: de::Error,
334
    {
335
        Ok(Value::Static(StaticNode::I64(i64::from(value))))
×
336
    }
337

338
    #[cfg_attr(not(feature = "no-inline"), inline)]
339
    fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
×
340
    where
341
        E: de::Error,
342
    {
343
        Ok(Value::Static(StaticNode::I64(i64::from(value))))
×
344
    }
345

346
    #[cfg_attr(not(feature = "no-inline"), inline)]
347
    fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
×
348
    where
349
        E: de::Error,
350
    {
351
        Ok(Value::Static(StaticNode::I64(i64::from(value))))
×
352
    }
353

354
    #[cfg_attr(not(feature = "no-inline"), inline)]
355
    fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
×
356
    where
357
        E: de::Error,
358
    {
359
        Ok(Value::Static(StaticNode::I64(value)))
×
360
    }
361

362
    #[cfg(feature = "128bit")]
363
    #[cfg_attr(not(feature = "no-inline"), inline)]
364
    fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
365
    where
366
        E: de::Error,
367
    {
368
        Ok(Value::Static(StaticNode::I128(value)))
×
369
    }
370

371
    /****************** u64 ******************/
372

373
    #[cfg_attr(not(feature = "no-inline"), inline)]
374
    fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
×
375
    where
376
        E: de::Error,
377
    {
378
        Ok(Value::Static(StaticNode::U64(u64::from(value))))
×
379
    }
380

381
    #[cfg_attr(not(feature = "no-inline"), inline)]
382
    fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E>
×
383
    where
384
        E: de::Error,
385
    {
386
        Ok(Value::Static(StaticNode::U64(u64::from(value))))
×
387
    }
388

389
    #[cfg_attr(not(feature = "no-inline"), inline)]
390
    fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
×
391
    where
392
        E: de::Error,
393
    {
394
        Ok(Value::Static(StaticNode::U64(u64::from(value))))
×
395
    }
396

397
    #[cfg_attr(not(feature = "no-inline"), inline)]
398
    fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
3✔
399
    where
400
        E: de::Error,
401
    {
402
        Ok(Value::Static(StaticNode::U64(value)))
3✔
403
    }
404

405
    #[cfg(feature = "128bit")]
406
    #[cfg_attr(not(feature = "no-inline"), inline)]
407
    fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
408
    where
409
        E: de::Error,
410
    {
411
        Ok(Value::Static(StaticNode::U128(value)))
×
412
    }
413

414
    /****************** f64 ******************/
415

416
    #[cfg_attr(not(feature = "no-inline"), inline)]
417
    fn visit_f32<E>(self, value: f32) -> Result<Self::Value, E>
×
418
    where
419
        E: de::Error,
420
    {
421
        Ok(Value::Static(StaticNode::F64(f64::from(value))))
×
422
    }
423

424
    #[cfg_attr(not(feature = "no-inline"), inline)]
425
    fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
2✔
426
    where
427
        E: de::Error,
428
    {
429
        Ok(Value::Static(StaticNode::F64(value)))
2✔
430
    }
431

432
    /****************** stringy stuff ******************/
433
    #[cfg_attr(not(feature = "no-inline"), inline)]
434
    fn visit_char<E>(self, value: char) -> Result<Self::Value, E>
435
    where
436
        E: de::Error,
437
    {
438
        Ok(Value::from(value.to_string()))
×
439
    }
440

441
    #[cfg_attr(not(feature = "no-inline"), inline)]
442
    fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
4✔
443
    where
444
        E: de::Error,
445
    {
446
        Ok(Value::from(value))
4✔
447
    }
448

449
    #[cfg_attr(not(feature = "no-inline"), inline)]
450
    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1✔
451
    where
452
        E: de::Error,
453
    {
454
        Ok(Value::String(value.to_owned().into()))
1✔
455
    }
456

457
    #[cfg_attr(not(feature = "no-inline"), inline)]
458
    fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
459
    where
460
        E: de::Error,
461
    {
462
        Ok(Value::String(value.into()))
×
463
    }
464

465
    /****************** byte stuff ******************/
466

467
    #[cfg_attr(not(feature = "no-inline"), inline)]
468
    fn visit_borrowed_bytes<E>(self, value: &'de [u8]) -> Result<Self::Value, E>
×
469
    where
470
        E: de::Error,
471
    {
472
        Ok(Value::Bytes(value.into()))
×
473
    }
474
    /*
475

476
    #[cfg_attr(not(feature = "no-inline"), inline)]
477
    fn visit_str<E>(self, value: &[u8]) -> Result<Self::Value, E>
478
    where
479
    'a: 'de
480
        E: de::Error,
481
    {
482
      Ok(Value::String(value))
483
    }
484

485
    #[cfg_attr(not(feature = "no-inline"), inline)]
486
    fn visit_string<E>(self, value: Vec<u8>) -> Result<Self::Value, E>
487
    where
488
        E: de::Error,
489
    {
490
      Ok(Value::String(&value))
491
    }
492
     */
493
    /****************** nested stuff ******************/
494

495
    #[cfg_attr(not(feature = "no-inline"), inline)]
496
    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
4✔
497
    where
498
        A: MapAccess<'de>,
499
    {
500
        let size = map.size_hint().unwrap_or_default();
9✔
501

502
        let mut m = Object::with_capacity(size);
4✔
503
        while let Some(k) = map.next_key::<&str>()? {
16✔
504
            let v = map.next_value()?;
8✔
505
            m.insert(k.into(), v);
12✔
506
        }
507
        Ok(Value::from(m))
4✔
508
    }
509

510
    #[cfg_attr(not(feature = "no-inline"), inline)]
511
    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
3✔
512
    where
513
        A: SeqAccess<'de>,
514
    {
515
        let size = seq.size_hint().unwrap_or_default();
6✔
516

517
        let mut v = Vec::with_capacity(size);
3✔
518
        while let Some(e) = seq.next_element()? {
15✔
519
            v.push(e);
3✔
520
        }
521
        Ok(Value::Array(v))
3✔
522
    }
523
}
524

525
/// Returns a struct populated against the DOM value via serde deserialization
526
///
527
/// # Errors
528
///
529
/// Will return Err if the DOM value cannot be deserialized to the target struct  
530
pub fn structurize<'de, T>(value: Value<'de>) -> crate::error::Result<T>
28✔
531
where
532
    T: de::Deserialize<'de>,
533
{
534
    match T::deserialize(value) {
28✔
535
        Ok(t) => Ok(t),
28✔
536
        Err(e) => Err(Error::Serde(e.to_string())),
3✔
537
    }
538
}
539

540
#[cfg(test)]
541
mod test {
542
    use crate::error::Result;
543
    use crate::structurize;
544

545
    #[derive(serde::Deserialize, Debug)]
546
    pub struct SO {}
547

548
    #[derive(serde::Deserialize, Debug)]
549
    pub struct S {
550
        pub o: Option<SO>,
551
        pub s: Option<String>,
552
        pub b: Option<bool>,
553
        pub a: Option<Vec<String>>,
554
        pub uw: Option<u8>,
555
        pub ux: Option<u16>,
556
        pub uy: Option<u32>,
557
        pub uz: Option<u64>,
558
        pub sw: Option<i8>,
559
        pub sx: Option<i16>,
560
        pub sy: Option<i32>,
561
        pub sz: Option<i64>,
562
        pub fx: Option<f32>,
563
        pub fy: Option<f64>,
564
    }
565

566
    #[derive(serde::Deserialize, Debug)]
567
    pub struct N {
568
        pub o: SO,
569
        pub s: String,
570
        pub b: bool,
571
        pub a: Vec<String>,
572
        pub uw: u8,
573
        pub ux: u16,
574
        pub uy: u32,
575
        pub uz: u64,
576
        pub sw: i8,
577
        pub sx: i16,
578
        pub sy: i32,
579
        pub sz: i64,
580
        pub fx: f32,
581
        pub fy: f64,
582
    }
583

584
    #[test]
585
    fn option_field_absent() -> Result<()> {
3✔
586
        let mut raw_json = r#"{}"#.to_string();
1✔
587
        let result: Result<S> =
2✔
588
            structurize(crate::parse_to_value(unsafe { raw_json.as_bytes_mut() })?);
589
        assert!(result.is_ok());
1✔
590

591
        let mut raw_json = r#"{}"#.to_string();
1✔
592
        let result: Result<N> =
2✔
593
            structurize(crate::parse_to_value(unsafe { raw_json.as_bytes_mut() })?);
594
        assert!(result.is_err());
1✔
595

596
        Ok(())
1✔
597
    }
598

599
    #[test]
600
    fn option_field_present() -> Result<()> {
3✔
601
        let mut raw_json = r#"{
1✔
602
            "o": {},
603
            "b": true,
604
            "s": "snot",
605
            "a": [],
606
            "uw": 0,
607
            "ux": 0,
608
            "uy": 0,
609
            "uz": 0,
610
            "sw": 0,
611
            "sx": 0,
612
            "sy": 0,
613
            "sz": 0,
614
            "fx": 0,
615
            "fy": 0
616
        }"#
617
        .to_string();
618
        let result: Result<S> =
2✔
619
            structurize(crate::parse_to_value(unsafe { raw_json.as_bytes_mut() })?);
620
        assert!(result.is_ok());
1✔
621

622
        let result: Result<N> =
2✔
623
            structurize(crate::parse_to_value(unsafe { raw_json.as_bytes_mut() })?);
624
        assert!(result.is_ok());
1✔
625

626
        let mut raw_json = r#"{}"#.to_string();
1✔
627
        let result: Result<S> =
2✔
628
            structurize(crate::parse_to_value(unsafe { raw_json.as_bytes_mut() })?);
629
        assert!(result.is_ok());
1✔
630

631
        Ok(())
1✔
632
    }
633
}
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

© 2024 Coveralls, Inc