1
#![doc = include_str!("../crate-docs.md")]
2
#![forbid(unsafe_code)]
3
#![warn(
4
    clippy::cargo,
5
    missing_docs,
6
    // clippy::missing_docs_in_private_items,
7
    clippy::pedantic,
8
    future_incompatible,
9
    rust_2018_idioms,
10
)]
11
#![allow(
12
    clippy::missing_errors_doc, // TODO clippy::missing_errors_doc
13
    clippy::option_if_let_else,
14
    clippy::used_underscore_binding, // false positive with tracing
15
    clippy::module_name_repetitions,
16
)]
17

            
18
/// Types for deserializing pots.
19
pub mod de;
20
mod error;
21
/// Low-level interface for reading and writing the pot format.
22
pub mod format;
23
/// Types for reading data.
24
pub mod reader;
25
/// Types for serializing pots.
26
pub mod ser;
27
mod value;
28
use std::io::Read;
29

            
30
use byteorder::WriteBytesExt;
31

            
32
pub use self::error::Error;
33
pub use self::value::{OwnedValue, Value, ValueError, ValueIter};
34
/// A result alias that returns [`Error`].
35
pub type Result<T, E = Error> = std::result::Result<T, E>;
36
use serde::de::DeserializeOwned;
37
use serde::{Deserialize, Serialize};
38

            
39
use crate::de::SymbolMapRef;
40
use crate::reader::IoReader;
41

            
42
/// Serialize `value` using Pot into a `Vec<u8>`.
43
///
44
/// ```rust
45
/// let serialized = pot::to_vec(&"hello world").unwrap();
46
/// let deserialized = pot::from_slice::<String>(&serialized).unwrap();
47
/// assert_eq!(deserialized, "hello world");
48
/// ```
49
#[inline]
50
1095
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
51
1095
where
52
1095
    T: Serialize,
53
1095
{
54
1095
    Config::default().serialize(value)
55
1095
}
56

            
57
/// Serialize `value` using Pot into `writer`.
58
///
59
/// ```rust
60
/// let mut serialized = Vec::new();
61
/// pot::to_writer(&"hello world", &mut serialized).unwrap();
62
/// let deserialized = pot::from_reader::<String, _>(&serialized[..]).unwrap();
63
/// assert_eq!(deserialized, "hello world");
64
/// ```
65
#[inline]
66
59
pub fn to_writer<T, W>(value: &T, writer: W) -> Result<()>
67
59
where
68
59
    T: Serialize,
69
59
    W: WriteBytesExt,
70
59
{
71
59
    Config::default().serialize_into(value, writer)
72
59
}
73

            
74
/// Restores a previously Pot-serialized value from a slice.
75
///
76
/// ```rust
77
/// let serialized = pot::to_vec(&"hello world").unwrap();
78
/// let deserialized = pot::from_slice::<String>(&serialized).unwrap();
79
/// assert_eq!(deserialized, "hello world");
80
/// ```
81
#[inline]
82
130
pub fn from_slice<'a, T>(serialized: &'a [u8]) -> Result<T>
83
130
where
84
130
    T: Deserialize<'a>,
85
130
{
86
130
    Config::default().deserialize(serialized)
87
130
}
88

            
89
/// Restores a previously Pot-serialized value from a [`Read`] implementer.
90
///
91
/// ```rust
92
/// let mut serialized = Vec::new();
93
/// pot::to_writer(&"hello world", &mut serialized).unwrap();
94
/// let deserialized = pot::from_reader::<String, _>(&serialized[..]).unwrap();
95
/// assert_eq!(deserialized, "hello world");
96
/// ```
97
#[inline]
98
58
pub fn from_reader<T, R>(reader: R) -> Result<T>
99
58
where
100
58
    T: DeserializeOwned,
101
58
    R: Read,
102
58
{
103
58
    Config::default().deserialize_from(reader)
104
58
}
105

            
106
/// Serialization and deserialization configuration.
107
#[must_use]
108
#[derive(Clone, Debug)]
109
pub struct Config {
110
    allocation_budget: usize,
111
}
112

            
113
impl Default for Config {
114
    #[inline]
115
1347
    fn default() -> Self {
116
1347
        Self {
117
1347
            allocation_budget: usize::MAX,
118
1347
        }
119
1347
    }
120
}
121

            
122
impl Config {
123
    /// Sets the maximum number of bytes able to be allocated. This is not
124
    /// guaranteed to be perfectly accurate, due to the limitations of serde
125
    /// deserializers. Pot can keep track of how many bytes it thinks its
126
    /// allocating, but a deserializer can always allocate more memory than Pot
127
    /// can be aware of.
128
    ///
129
    /// The default allocation budget is [`usize::MAX`].
130
    #[inline]
131
5
    pub const fn allocation_budget(mut self, budget: usize) -> Self {
132
5
        self.allocation_budget = budget;
133
5
        self
134
5
    }
135

            
136
    /// Deserializes a value from a slice using the configured options.
137
    #[inline]
138
135
    pub fn deserialize<'de, T>(&self, serialized: &'de [u8]) -> Result<T>
139
135
    where
140
135
        T: Deserialize<'de>,
141
135
    {
142
135
        let mut deserializer = de::Deserializer::from_slice(serialized, self.allocation_budget)?;
143
134
        let t = T::deserialize(&mut deserializer)?;
144
123
        if deserializer.end_of_input() {
145
123
            Ok(t)
146
        } else {
147
            Err(Error::TrailingBytes)
148
        }
149
135
    }
150

            
151
    /// Deserializes a value from a [`Read`] implementer using the configured
152
    /// options.
153
    #[inline]
154
58
    pub fn deserialize_from<T, R: Read>(&self, reader: R) -> Result<T>
155
58
    where
156
58
        T: DeserializeOwned,
157
58
    {
158
58
        let mut deserializer = de::Deserializer::from_read(
159
58
            IoReader::new(reader),
160
58
            SymbolMapRef::temporary(),
161
58
            self.allocation_budget,
162
58
        )?;
163
58
        T::deserialize(&mut deserializer)
164
58
    }
165

            
166
    /// Serializes a value to a `Vec` using the configured options.
167
    #[inline]
168
1095
    pub fn serialize<T: Serialize>(&self, value: &T) -> Result<Vec<u8>> {
169
1095
        let mut output = Vec::new();
170
1095
        self.serialize_into(value, &mut output)?;
171
1095
        Ok(output)
172
1095
    }
173

            
174
    /// Serializes a value to a writer using the configured options.
175
    #[allow(clippy::unused_self)]
176
    #[inline]
177
1154
    pub fn serialize_into<T, W>(&self, value: &T, writer: W) -> Result<()>
178
1154
    where
179
1154
        T: Serialize,
180
1154
        W: WriteBytesExt,
181
1154
    {
182
1154
        let mut serializer = ser::Serializer::new(writer)?;
183
1154
        value.serialize(&mut serializer)
184
1154
    }
185
}
186

            
187
#[cfg(test)]
188
mod tests {
189
    use std::borrow::Cow;
190
    use std::marker::PhantomData;
191
    use std::sync::OnceLock;
192

            
193
    use serde::{Deserializer, Serializer};
194
    use serde_derive::{Deserialize, Serialize};
195

            
196
    use super::*;
197
    use crate::format::{Float, Integer, CURRENT_VERSION};
198
    use crate::value::Value;
199

            
200
58
    fn init_tracing() {
201
58
        static INITIALIZED: OnceLock<()> = OnceLock::new();
202
58

            
203
58
        INITIALIZED.get_or_init(|| {
204
1
            #[cfg(not(feature = "tracing"))]
205
1
            println!("To see additional logs, run tests with the `tracing` feature enabled");
206
1

            
207
1
            tracing_subscriber::fmt()
208
1
                .pretty()
209
1
                // Enable everything.
210
1
                .with_max_level(tracing::Level::TRACE)
211
1
                .with_span_events(tracing_subscriber::fmt::format::FmtSpan::ENTER)
212
1
                // Set this to be the default, global collector for this application.
213
1
                .init();
214
58
        });
215
58
    }
216

            
217
58
    fn test_serialization<S: Serialize + for<'de> Deserialize<'de> + PartialEq + Debug>(
218
58
        value: &S,
219
58
        check_length: Option<usize>,
220
58
    ) {
221
116
        test_serialization_with(value, check_length, |value, deserialized| {
222
116
            assert_eq!(value, deserialized);
223
116
        });
224
58
    }
225

            
226
58
    fn test_serialization_with<
227
58
        S: Serialize + for<'de> Deserialize<'de> + PartialEq + Debug,
228
58
        F: FnMut(&S, &S),
229
58
    >(
230
58
        value: &S,
231
58
        check_length: Option<usize>,
232
58
        mut callback: F,
233
58
    ) {
234
58
        init_tracing();
235
58
        let bytes = to_vec(&value).unwrap();
236
58
        println!("{value:?}: {bytes:02x?}");
237
58
        let deserialized = from_slice::<S>(&bytes).unwrap();
238
58
        callback(value, &deserialized);
239
58
        if let Some(check_length) = check_length {
240
            // Subtract 4 bytes from the serialized output to account for the header.
241
42
            assert_eq!(bytes.len() - 4, check_length);
242
16
        }
243

            
244
        // Do the same, but using the reader interface.
245
58
        let mut bytes = Vec::new();
246
58
        to_writer(value, &mut bytes).unwrap();
247
58
        println!("{value:?}: {bytes:02x?}");
248
58
        let deserialized = from_reader(&bytes[..]).unwrap();
249
58
        callback(value, &deserialized);
250
58
    }
251

            
252
    use std::fmt::Debug;
253

            
254
406
    #[derive(Serialize, PartialEq, Deserialize, Debug, Default)]
255
    struct NumbersStruct {
256
        u8: u8,
257
        u16: u16,
258
        char: char,
259
        u32: u32,
260
        u64: u64,
261
        u128: u128,
262
        i8: i8,
263
        i16: i16,
264
        i32: i32,
265
        i64: i64,
266
        i128: i128,
267
        f32: f32,
268
        f64: f64,
269
    }
270

            
271
54
    #[derive(Serialize, PartialEq, Deserialize, Debug)]
272
    enum EnumVariants {
273
        Unit,
274
        Tuple(u64),
275
        TupleTwoArgs(u64, u64),
276
        Struct { arg: u64 },
277
    }
278

            
279
1
    #[test]
280
1
    fn numbers() {
281
1
        test_serialization(&NumbersStruct::default(), None);
282
1
        test_serialization(
283
1
            &NumbersStruct {
284
1
                u8: u8::MAX,
285
1
                u16: u16::MAX,
286
1
                char: char::MAX,
287
1
                u32: u32::MAX,
288
1
                u64: u64::MAX,
289
1
                u128: u128::MAX,
290
1
                i8: i8::MIN,
291
1
                i16: i16::MIN,
292
1
                i32: i32::MIN,
293
1
                i64: i64::MIN,
294
1
                i128: i128::MIN,
295
1
                f32: 1.,
296
1
                f64: 1.,
297
1
            },
298
1
            None,
299
1
        );
300
1
    }
301

            
302
1
    #[test]
303
1
    fn number_packing() {
304
1
        test_serialization(&0_u128, Some(2));
305
1
        test_serialization(&(2_u128.pow(8) - 1), Some(2));
306
1
        test_serialization(&2_u128.pow(8), Some(3));
307
1
        test_serialization(&(2_u128.pow(16) - 1), Some(3));
308
1
        test_serialization(&2_u128.pow(16), Some(4));
309
1
        test_serialization(&(2_u128.pow(24) - 1), Some(4));
310
1
        test_serialization(&2_u128.pow(24), Some(5));
311
1
        test_serialization(&(2_u128.pow(32) - 1), Some(5));
312
1
        test_serialization(&2_u128.pow(32), Some(7));
313
1
        test_serialization(&(2_u128.pow(48) - 1), Some(7));
314
1
        test_serialization(&2_u128.pow(48), Some(9));
315
1
        test_serialization(&(2_u128.pow(64) - 1), Some(9));
316
1
        test_serialization(&2_u128.pow(64), Some(17));
317
1

            
318
1
        test_serialization(&0_i128, Some(2));
319
1
        test_serialization(&(2_i128.pow(7) - 1), Some(2));
320
1
        test_serialization(&2_i128.pow(7), Some(3));
321
1
        test_serialization(&(2_i128.pow(15) - 1), Some(3));
322
1
        test_serialization(&2_i128.pow(15), Some(4));
323
1
        test_serialization(&(2_i128.pow(23) - 1), Some(4));
324
1
        test_serialization(&2_i128.pow(23), Some(5));
325
1
        test_serialization(&(2_i128.pow(31) - 1), Some(5));
326
1
        test_serialization(&2_i128.pow(31), Some(7));
327
1
        test_serialization(&(2_i128.pow(47) - 1), Some(7));
328
1
        test_serialization(&2_i128.pow(47), Some(9));
329
1
        test_serialization(&-(2_i128.pow(7)), Some(2));
330
1
        test_serialization(&-(2_i128.pow(7) + 1), Some(3));
331
1
        test_serialization(&-(2_i128.pow(15)), Some(3));
332
1
        test_serialization(&-(2_i128.pow(15) + 1), Some(4));
333
1
        test_serialization(&-(2_i128.pow(23)), Some(4));
334
1
        test_serialization(&-(2_i128.pow(23) + 1), Some(5));
335
1
        test_serialization(&-(2_i128.pow(31)), Some(5));
336
1
        test_serialization(&-(2_i128.pow(31) + 1), Some(7));
337
1
        test_serialization(&-(2_i128.pow(47)), Some(7));
338
1
        test_serialization(&-(2_i128.pow(47) + 1), Some(9));
339
1
        test_serialization(&-(2_i128.pow(63)), Some(9));
340
1
        test_serialization(&-(2_i128.pow(63) + 1), Some(17));
341
1

            
342
1
        // Float packing relies on bitwise conversions and is lossless.
343
1
        test_serialization(&f64::INFINITY, Some(3));
344
1
        test_serialization(&f64::NEG_INFINITY, Some(3));
345
1
        test_serialization(&0_f64, Some(3));
346
1
        test_serialization(&-0_f64, Some(3));
347
1
        test_serialization(&0.1_f64, Some(9));
348
1
        test_serialization(&0.1_f32, Some(5));
349
1
    }
350

            
351
1
    #[test]
352
1
    fn tuples() {
353
1
        test_serialization(&(1, true, 3), None);
354
1
    }
355

            
356
1
    #[test]
357
1
    fn enums() {
358
1
        test_serialization(&EnumVariants::Unit, None);
359
1

            
360
1
        test_serialization(&EnumVariants::Tuple(0), None);
361
1

            
362
1
        test_serialization(&EnumVariants::TupleTwoArgs(1, 2), None);
363
1

            
364
1
        test_serialization(&EnumVariants::Struct { arg: 3 }, None);
365
1

            
366
1
        test_serialization(&Some(EnumVariants::Unit), None);
367
1
    }
368

            
369
1
    #[test]
370
1
    fn vectors() {
371
1
        test_serialization(&vec![0_u64, 1], None);
372
1
        test_serialization(
373
1
            &vec![NumbersStruct::default(), NumbersStruct::default()],
374
1
            None,
375
1
        );
376
1
    }
377

            
378
1
    #[test]
379
1
    fn option() {
380
1
        test_serialization(&Option::<u64>::None, None);
381
1
        test_serialization(&Some(0_u64), None);
382
1
        test_serialization(&Some(u64::MAX), None);
383
1
    }
384

            
385
1
    #[test]
386
1
    fn phantom() {
387
1
        test_serialization(&PhantomData::<u64>, None);
388
1
    }
389

            
390
49
    #[derive(Serialize, PartialEq, Deserialize, Debug, Default)]
391
    struct StringsAndBytes<'a> {
392
        bytes: Cow<'a, [u8]>,
393
        #[serde(with = "serde_bytes")]
394
        bytes_borrowed: Cow<'a, [u8]>,
395
        #[serde(with = "serde_bytes")]
396
        serde_bytes_byte_slice: &'a [u8],
397
        #[serde(with = "serde_bytes")]
398
        serde_bytes_byte_vec: Vec<u8>,
399
        str_ref: &'a str,
400
        string: String,
401
    }
402

            
403
1
    #[test]
404
1
    fn borrowing_data() {
405
1
        let original = StringsAndBytes {
406
1
            bytes: Cow::Borrowed(b"hello"),
407
1
            bytes_borrowed: Cow::Borrowed(b"hello"),
408
1
            serde_bytes_byte_slice: b"hello",
409
1
            serde_bytes_byte_vec: b"world".to_vec(),
410
1
            str_ref: "hello",
411
1
            string: String::from("world"),
412
1
        };
413
1
        let serialized = to_vec(&original).unwrap();
414
1
        let deserialized = from_slice(&serialized).unwrap();
415
1
        assert_eq!(original, deserialized);
416
1
        assert!(matches!(deserialized.bytes_borrowed, Cow::Borrowed(_)));
417
1
    }
418

            
419
1
    #[test]
420
1
    fn limiting_input() {
421
1
        let original = StringsAndBytes {
422
1
            bytes: Cow::Borrowed(b"hello"),
423
1
            bytes_borrowed: Cow::Borrowed(b"hello"),
424
1
            serde_bytes_byte_slice: b"hello",
425
1
            serde_bytes_byte_vec: b"world".to_vec(),
426
1
            str_ref: "hello",
427
1
            string: String::from("world"),
428
1
        };
429
1
        let serialized = to_vec(&original).unwrap();
430
1
        // There are 6 values that contain 5 bytes each. A limit of 30 should be perfect.
431
1
        assert!(Config::default()
432
1
            .allocation_budget(30)
433
1
            .deserialize::<StringsAndBytes<'_>>(&serialized)
434
1
            .is_ok());
435
1
        assert!(Config::default()
436
1
            .allocation_budget(29)
437
1
            .deserialize::<StringsAndBytes<'_>>(&serialized)
438
1
            .is_err());
439

            
440
        // Test number limits.
441
1
        let serialized = to_vec(&NumbersStruct {
442
1
            u8: u8::MAX,
443
1
            u16: u16::MAX,
444
1
            char: char::MAX,
445
1
            u32: u32::MAX,
446
1
            u64: u64::MAX,
447
1
            u128: u128::MAX,
448
1
            i8: i8::MIN,
449
1
            i16: i16::MIN,
450
1
            i32: i32::MIN,
451
1
            i64: i64::MIN,
452
1
            i128: i128::MIN,
453
1
            f32: f32::MAX,
454
1
            f64: f64::MIN,
455
1
        })
456
1
        .unwrap();
457
1
        assert!(Config::default()
458
1
            .allocation_budget(78)
459
1
            .deserialize::<NumbersStruct>(&serialized)
460
1
            .is_ok());
461
1
        assert!(Config::default()
462
1
            .allocation_budget(77)
463
1
            .deserialize::<NumbersStruct>(&serialized)
464
1
            .is_err());
465
1
    }
466

            
467
2
    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
468
    struct TupleStruct(u32, u8);
469

            
470
1
    #[test]
471
1
    fn tuple_struct() {
472
1
        test_serialization(&TupleStruct(1, 2), None);
473
1
    }
474

            
475
1
    #[test]
476
1
    fn value() {
477
1
        macro_rules! roundtrip {
478
1
            ($value:expr) => {{
479
1
                assert_eq!(
480
1
                    from_slice::<Value<'_>>(&to_vec(&$value).unwrap()).unwrap(),
481
1
                    $value
482
1
                );
483
1
            }};
484
1
        }
485
1

            
486
1
        roundtrip!(Value::None);
487
1
        roundtrip!(Value::Unit);
488
1
        roundtrip!(Value::Bool(true));
489
1
        roundtrip!(Value::Bool(false));
490
1
        roundtrip!(Value::Integer(Integer::from(i8::MAX)));
491
1
        roundtrip!(Value::Integer(Integer::from(i16::MAX)));
492
1
        roundtrip!(Value::Integer(Integer::from(i32::MAX)));
493
1
        roundtrip!(Value::Integer(Integer::from(i64::MAX)));
494
1
        roundtrip!(Value::Integer(Integer::from(i128::MAX)));
495
1
        roundtrip!(Value::Integer(Integer::from(u8::MAX)));
496
1
        roundtrip!(Value::Integer(Integer::from(u16::MAX)));
497
1
        roundtrip!(Value::Integer(Integer::from(u32::MAX)));
498
1
        roundtrip!(Value::Integer(Integer::from(u64::MAX)));
499
1
        roundtrip!(Value::Integer(Integer::from(u128::MAX)));
500
1
        roundtrip!(Value::Float(Float::from(std::f64::consts::PI)));
501
1
        roundtrip!(Value::Float(Float::from(std::f32::consts::PI)));
502
1
        roundtrip!(Value::Sequence(vec![Value::None]));
503
1
        roundtrip!(Value::Mappings(vec![(Value::None, Value::Unit)]));
504

            
505
1
        let original_value = Value::Bytes(Cow::Borrowed(b"hello"));
506
1
        let encoded_bytes = to_vec(&original_value).unwrap();
507
1
        let borrowed_decoded: Value<'_> = from_slice(&encoded_bytes).unwrap();
508
1
        assert_eq!(Value::String(Cow::Borrowed("hello")), borrowed_decoded);
509
1
        assert!(matches!(borrowed_decoded, Value::String(Cow::Borrowed(_))));
510

            
511
1
        let original_value = Value::Bytes(Cow::Borrowed(b"\xFE\xED\xD0\xD0"));
512
1
        let encoded_bytes = to_vec(&original_value).unwrap();
513
1
        let borrowed_decoded: Value<'_> = from_slice(&encoded_bytes).unwrap();
514
1
        assert_eq!(
515
1
            Value::Bytes(Cow::Borrowed(b"\xFE\xED\xD0\xD0")),
516
1
            borrowed_decoded
517
1
        );
518
1
        assert!(matches!(borrowed_decoded, Value::Bytes(Cow::Borrowed(_))));
519
1
    }
520

            
521
1
    #[test]
522
1
    fn incompatible_version() {
523
1
        let mut incompatible_header = Vec::new();
524
1
        format::write_header(&mut incompatible_header, CURRENT_VERSION + 1).unwrap();
525
1
        assert!(matches!(
526
1
            from_slice::<()>(&incompatible_header),
527
            Err(Error::IncompatibleVersion)
528
        ));
529
1
    }
530

            
531
1
    #[test]
532
1
    fn invalid_char_cast() {
533
1
        let bytes = to_vec(&0x11_0000_u32).unwrap();
534

            
535
1
        assert!(matches!(
536
1
            from_slice::<char>(&bytes),
537
            Err(Error::InvalidUtf8(_))
538
        ));
539
1
    }
540

            
541
1
    #[test]
542
1
    fn bytes_to_identifier() {
543
1
        let mut valid_bytes = Vec::new();
544
1
        format::write_header(&mut valid_bytes, CURRENT_VERSION).unwrap();
545
1
        format::write_named(&mut valid_bytes).unwrap();
546
1
        format::write_bytes(&mut valid_bytes, b"Unit").unwrap();
547
1

            
548
1
        assert_eq!(
549
1
            from_slice::<EnumVariants>(&valid_bytes).unwrap(),
550
1
            EnumVariants::Unit
551
1
        );
552

            
553
1
        let mut invalid_bytes = Vec::new();
554
1
        format::write_header(&mut invalid_bytes, CURRENT_VERSION).unwrap();
555
1
        format::write_named(&mut invalid_bytes).unwrap();
556
1
        format::write_bytes(&mut invalid_bytes, &0xFFFF_FFFF_u32.to_be_bytes()).unwrap();
557

            
558
1
        assert!(matches!(
559
1
            from_slice::<EnumVariants>(&invalid_bytes),
560
            Err(Error::InvalidUtf8(_))
561
        ));
562
1
    }
563

            
564
1
    #[test]
565
1
    fn invalid_symbol() {
566
1
        let mut valid_bytes = Vec::new();
567
1
        format::write_header(&mut valid_bytes, CURRENT_VERSION).unwrap();
568
1
        format::write_atom_header(&mut valid_bytes, format::Kind::Symbol, 4).unwrap();
569
1
        format::write_bytes(&mut valid_bytes, &0xFFFF_FFFF_u32.to_be_bytes()).unwrap();
570

            
571
1
        assert!(matches!(
572
1
            from_slice::<Value<'_>>(&valid_bytes),
573
            Err(Error::InvalidUtf8(_))
574
        ));
575
1
    }
576

            
577
1
    #[test]
578
1
    fn unknown_special() {
579
1
        let mut invalid_bytes = Vec::new();
580
1
        format::write_header(&mut invalid_bytes, CURRENT_VERSION).unwrap();
581
1
        format::write_atom_header(
582
1
            &mut invalid_bytes,
583
1
            format::Kind::Special,
584
1
            format::SPECIAL_COUNT,
585
1
        )
586
1
        .unwrap();
587
1

            
588
1
        assert!(from_slice::<()>(&invalid_bytes).is_err());
589
1
    }
590

            
591
    /// In `BonsaiDb`, sometimes it's nice to use a `()` as an associated type
592
    /// as a default. To allow changing data that was previously serialized as a
593
    /// `()` but now has a new type, Pot allows converting between unit types
594
    /// and defaults of all major serialized types. The net effect is if you
595
    /// start with a derived `BonsaiDb` view with no `value =` argument, `()` is
596
    /// used instead. With this flexibility, changing the value type to another
597
    /// type will sometimes be able to work without requiring rebuilding the
598
    /// views on deployment.
599
1
    #[test]
600
    #[allow(clippy::cognitive_complexity)]
601
1
    fn unit_adaptations() {
602
1
        #[derive(Deserialize)]
603
1
        struct Test {
604
1
            #[serde(default)]
605
1
            value: u32,
606
1
        }
607
1

            
608
1
        let unit = to_vec(&()).unwrap();
609
1
        assert!(from_slice::<Option<()>>(&unit).unwrap().is_some());
610
1
        assert_eq!(from_slice::<Test>(&unit).unwrap().value, 0);
611
1
        assert_eq!(from_slice::<&[u8]>(&unit).unwrap(), b"");
612
1
        assert_eq!(from_slice::<serde_bytes::ByteBuf>(&unit).unwrap(), b"");
613
1
        assert_eq!(from_slice::<&str>(&unit).unwrap(), "");
614
1
        assert_eq!(from_slice::<u8>(&unit).unwrap(), 0);
615
1
        assert_eq!(from_slice::<u16>(&unit).unwrap(), 0);
616
1
        assert_eq!(from_slice::<u32>(&unit).unwrap(), 0);
617
1
        assert_eq!(from_slice::<u64>(&unit).unwrap(), 0);
618
1
        assert_eq!(from_slice::<u128>(&unit).unwrap(), 0);
619
1
        assert_eq!(from_slice::<i8>(&unit).unwrap(), 0);
620
1
        assert_eq!(from_slice::<i16>(&unit).unwrap(), 0);
621
1
        assert_eq!(from_slice::<i32>(&unit).unwrap(), 0);
622
1
        assert_eq!(from_slice::<i64>(&unit).unwrap(), 0);
623
1
        assert_eq!(from_slice::<i128>(&unit).unwrap(), 0);
624
1
        assert!(!from_slice::<bool>(&unit).unwrap());
625

            
626
1
        let none = to_vec(&Option::<()>::None).unwrap();
627
1
        assert!(from_slice::<Option<()>>(&none).unwrap().is_none());
628
1
        assert!(from_slice::<Option<Test>>(&none).unwrap().is_none());
629
1
        assert_eq!(from_slice::<&[u8]>(&none).unwrap(), b"");
630
1
        assert_eq!(from_slice::<serde_bytes::ByteBuf>(&none).unwrap(), b"");
631
1
        assert_eq!(from_slice::<&str>(&none).unwrap(), "");
632
1
        assert_eq!(from_slice::<u8>(&none).unwrap(), 0);
633
1
        assert_eq!(from_slice::<u16>(&none).unwrap(), 0);
634
1
        assert_eq!(from_slice::<u32>(&none).unwrap(), 0);
635
1
        assert_eq!(from_slice::<u64>(&none).unwrap(), 0);
636
1
        assert_eq!(from_slice::<u128>(&none).unwrap(), 0);
637
1
        assert_eq!(from_slice::<i8>(&none).unwrap(), 0);
638
1
        assert_eq!(from_slice::<i16>(&none).unwrap(), 0);
639
1
        assert_eq!(from_slice::<i32>(&none).unwrap(), 0);
640
1
        assert_eq!(from_slice::<i64>(&none).unwrap(), 0);
641
1
        assert_eq!(from_slice::<i128>(&none).unwrap(), 0);
642
1
        assert!(!from_slice::<bool>(&none).unwrap());
643
1
    }
644

            
645
1
    #[test]
646
1
    fn invalid_numbers() {
647
1
        let mut invalid_float_byte_len = Vec::new();
648
1
        format::write_header(&mut invalid_float_byte_len, CURRENT_VERSION).unwrap();
649
1
        format::write_atom_header(&mut invalid_float_byte_len, format::Kind::Float, 0).unwrap();
650
1

            
651
1
        assert!(from_slice::<f32>(&invalid_float_byte_len).is_err());
652

            
653
1
        assert!(format::Float::read_from(
654
1
            format::Kind::Symbol,
655
1
            0,
656
1
            &mut &invalid_float_byte_len[..]
657
1
        )
658
1
        .is_err(),);
659

            
660
1
        let mut invalid_signed_byte_len = Vec::new();
661
1
        format::write_header(&mut invalid_signed_byte_len, CURRENT_VERSION).unwrap();
662
1
        format::write_atom_header(&mut invalid_signed_byte_len, format::Kind::Int, 10).unwrap();
663
1

            
664
1
        assert!(from_slice::<i32>(&invalid_signed_byte_len).is_err());
665

            
666
1
        assert!(format::Integer::read_from(
667
1
            format::Kind::Symbol,
668
1
            0,
669
1
            &mut &invalid_signed_byte_len[..]
670
1
        )
671
1
        .is_err(),);
672

            
673
1
        let mut invalid_unsigned_byte_len = Vec::new();
674
1
        format::write_header(&mut invalid_unsigned_byte_len, CURRENT_VERSION).unwrap();
675
1
        format::write_atom_header(&mut invalid_unsigned_byte_len, format::Kind::UInt, 10).unwrap();
676
1

            
677
1
        assert!(from_slice::<u32>(&invalid_unsigned_byte_len).is_err());
678
1
    }
679

            
680
1
    #[test]
681
    #[allow(clippy::unnecessary_mut_passed)] // It's necessary.
682
1
    fn not_human_readable() {
683
1
        let mut bytes = Vec::new();
684
1
        let mut serializer = ser::Serializer::new(&mut bytes).unwrap();
685
1
        assert!(!(&mut serializer).is_human_readable());
686
1
        ().serialize(&mut serializer).unwrap();
687
1

            
688
1
        let bytes = to_vec(&()).unwrap();
689
1
        let mut deserializer = de::Deserializer::from_slice(&bytes, usize::MAX).unwrap();
690
1
        assert!(!(&mut deserializer).is_human_readable());
691
1
    }
692

            
693
1
    #[test]
694
1
    fn unexpected_eof() {
695
1
        let mut invalid_bytes = Vec::new();
696
1
        format::write_header(&mut invalid_bytes, CURRENT_VERSION).unwrap();
697
1
        format::write_atom_header(&mut invalid_bytes, format::Kind::Bytes, 10).unwrap();
698
1
        assert!(matches!(
699
1
            from_slice::<Vec<u8>>(&invalid_bytes),
700
            Err(Error::Eof)
701
        ));
702
1
    }
703

            
704
1
    #[test]
705
1
    fn too_big_read() {
706
1
        let mut invalid_bytes = Vec::new();
707
1
        format::write_header(&mut invalid_bytes, CURRENT_VERSION).unwrap();
708
1
        format::write_atom_header(&mut invalid_bytes, format::Kind::Bytes, 10).unwrap();
709
1
        assert!(matches!(
710
1
            Config::default()
711
1
                .allocation_budget(9)
712
1
                .deserialize::<Vec<u8>>(&invalid_bytes),
713
            Err(Error::TooManyBytesRead)
714
        ));
715
1
    }
716

            
717
2
    #[derive(Serialize, Deserialize, Debug, PartialEq)]
718
    struct Flatten {
719
        #[serde(flatten)]
720
        structure: Flattened,
721
        #[serde(flatten)]
722
        enumeration: EnumVariants,
723
    }
724

            
725
6
    #[derive(Serialize, Deserialize, Debug, PartialEq)]
726
    struct Flattened {
727
        field: String,
728
    }
729

            
730
1
    #[test]
731
1
    fn test_flatten() {
732
1
        test_serialization(
733
1
            &Flatten {
734
1
                structure: Flattened {
735
1
                    field: String::from("flat"),
736
1
                },
737
1
                enumeration: EnumVariants::Struct { arg: 1 },
738
1
            },
739
1
            None,
740
1
        );
741
1
    }
742

            
743
1
    #[test]
744
1
    fn direct_value_serialization() {
745
8
        fn roundtrip<T: Serialize + for<'de> Deserialize<'de> + PartialEq + Debug>(value: &T) {
746
8
            let as_value = Value::from_serialize(value).unwrap();
747
8
            let deserialized = as_value.deserialize_as::<T>().unwrap();
748
8
            assert_eq!(&deserialized, value);
749
8
        }
750
1

            
751
1
        roundtrip(&NumbersStruct {
752
1
            u8: u8::MAX,
753
1
            u16: u16::MAX,
754
1
            char: char::MAX,
755
1
            u32: u32::MAX,
756
1
            u64: u64::MAX,
757
1
            u128: u128::MAX,
758
1
            i8: i8::MIN,
759
1
            i16: i16::MIN,
760
1
            i32: i32::MIN,
761
1
            i64: i64::MIN,
762
1
            i128: i128::MIN,
763
1
            f32: f32::MAX,
764
1
            f64: f64::MIN,
765
1
        });
766
1

            
767
1
        roundtrip(&EnumVariants::Struct { arg: 1 });
768
1
        roundtrip(&EnumVariants::Tuple(1));
769
1
        roundtrip(&EnumVariants::TupleTwoArgs(1, 2));
770
1
        roundtrip(&EnumVariants::Unit);
771
1
        roundtrip(&Some(1_u32));
772
1
        roundtrip(&"hello".to_string());
773
1
        roundtrip(&b"hello".to_vec());
774
1
    }
775

            
776
1
    #[test]
777
1
    fn borrowed_value_serialization() {
778
1
        #[track_caller]
779
2
        fn check<T, U>(value: &T)
780
2
        where
781
2
            T: Serialize + Debug,
782
2
            U: Debug + PartialEq<T> + for<'de> Deserialize<'de>,
783
2
        {
784
2
            let as_value = Value::from_serialize(value).unwrap();
785
2
            let deserialized = as_value.deserialize_as::<U>().unwrap();
786
2
            assert_eq!(&deserialized, value);
787
2
        }
788
1

            
789
1
        check::<_, Vec<u8>>(&b"hello");
790
1
        check::<_, String>(&"hello");
791
1
    }
792

            
793
1
    #[test]
794
1
    fn value_error() {
795
1
        #[derive(Debug)]
796
1
        struct Fallible;
797
1

            
798
1
        impl Serialize for Fallible {
799
1
            fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
800
1
            where
801
1
                S: Serializer,
802
1
            {
803
1
                Err(serde::ser::Error::custom("oh no!"))
804
1
            }
805
1
        }
806
1

            
807
1
        assert_eq!(
808
1
            Value::from_serialize(Fallible),
809
1
            Err(ValueError::Custom(String::from("oh no!")))
810
1
        );
811
1
    }
812

            
813
1
    #[test]
814
1
    fn persistent_symbols_slice() {
815
1
        let mut sender = ser::SymbolMap::default();
816
1
        let mut receiver = de::SymbolList::default();
817
1

            
818
1
        let mut bytes = sender.serialize_to_vec(&NumbersStruct::default()).unwrap();
819
1
        let _result = receiver.deserialize_slice::<NumbersStruct>(&bytes).unwrap();
820
1
        let symbol_count_after_first_send = receiver.len();
821
1
        let first_payload_len = bytes.len();
822
1

            
823
1
        // Send again, confirm the symbol list didn't grow.
824
1
        bytes.clear();
825
1
        sender
826
1
            .serialize_to(&mut bytes, &NumbersStruct::default())
827
1
            .unwrap();
828
1
        let _result = receiver.deserialize_slice::<NumbersStruct>(&bytes).unwrap();
829
1
        assert_eq!(symbol_count_after_first_send, receiver.len());
830
1
        println!(
831
1
            "First: {first_payload_len} bytes; Second: {} bytes",
832
1
            bytes.len()
833
1
        );
834
1
        assert!(first_payload_len > bytes.len());
835
1
    }
836

            
837
1
    #[test]
838
1
    fn persistent_symbols_read() {
839
1
        let mut sender = ser::SymbolMap::default();
840
1
        let mut receiver = de::SymbolList::default();
841
1

            
842
1
        let mut bytes = sender.serialize_to_vec(&NumbersStruct::default()).unwrap();
843
1
        let _result = receiver
844
1
            .deserialize_from::<NumbersStruct>(&bytes[..])
845
1
            .unwrap();
846
1
        let symbol_count_after_first_send = receiver.len();
847
1
        let first_payload_len = bytes.len();
848
1

            
849
1
        // Send again, confirm the symbol list didn't grow.
850
1
        bytes.clear();
851
1
        sender
852
1
            .serialize_to(&mut bytes, &NumbersStruct::default())
853
1
            .unwrap();
854
1
        let _result = receiver
855
1
            .deserialize_from::<NumbersStruct>(&bytes[..])
856
1
            .unwrap();
857
1
        assert_eq!(symbol_count_after_first_send, receiver.len());
858
1
        println!(
859
1
            "First: {first_payload_len} bytes; Second: {} bytes",
860
1
            bytes.len()
861
1
        );
862
1
        assert!(first_payload_len > bytes.len());
863
1
    }
864

            
865
1
    #[test]
866
1
    fn symbol_map_serialization() {
867
15
        #[derive(Serialize, Deserialize, Default, Eq, PartialEq, Debug)]
868
1
        struct Payload {
869
1
            a: usize,
870
1
            b: usize,
871
1
        }
872
1

            
873
1
        let mut sender = crate::ser::SymbolMap::default();
874
1
        assert!(sender.is_empty());
875
1
        let mut receiver = crate::de::SymbolMap::new();
876
1
        assert!(receiver.is_empty());
877

            
878
        // Send the first payload, populating the map.
879
1
        let mut bytes = sender.serialize_to_vec(&Payload::default()).unwrap();
880
1
        assert_eq!(sender.len(), 2);
881

            
882
1
        assert_eq!(
883
1
            receiver.deserialize_slice::<Payload>(&bytes).unwrap(),
884
1
            Payload::default()
885
1
        );
886
1
        assert_eq!(receiver.len(), 2);
887

            
888
        // Serialize the maps.
889
1
        let serialized_sender = crate::to_vec(&sender).unwrap();
890
1
        let serialized_receiver = crate::to_vec(&receiver).unwrap();
891
1
        // The serialization formats are the same despite using different
892
1
        // in-memory representations. This allows pre-serializing a dictionary
893
1
        // before starting the intial payload.
894
1
        assert_eq!(serialized_sender, serialized_receiver);
895
1
        let mut deserialized_sender =
896
1
            crate::from_slice::<crate::ser::SymbolMap>(&serialized_sender).unwrap();
897
1
        let mut deserialized_receiver =
898
1
            crate::from_slice::<crate::de::SymbolMap>(&serialized_receiver).unwrap();
899
1

            
900
1
        // Create a new payload and serialize it. Ensure the payloads produced
901
1
        // by the serialized map and the original map are identical.
902
1
        let new_payload = Payload { a: 1, b: 2 };
903
1
        bytes.clear();
904
1
        sender.serialize_to(&mut bytes, &new_payload).unwrap();
905
1
        let from_serialized_sender = deserialized_sender.serialize_to_vec(&new_payload).unwrap();
906
1
        assert_eq!(bytes, from_serialized_sender);
907

            
908
        // Deserialize the payload
909
1
        assert_eq!(
910
1
            receiver.deserialize_slice::<Payload>(&bytes).unwrap(),
911
1
            new_payload
912
1
        );
913
1
        assert_eq!(
914
1
            deserialized_receiver
915
1
                .deserialize_slice::<Payload>(&bytes)
916
1
                .unwrap(),
917
1
            new_payload
918
1
        );
919
1
    }
920

            
921
1
    #[test]
922
1
    fn symbol_map_population() {
923
1
        let mut map = crate::ser::SymbolMap::default();
924
1
        map.populate_from(&NumbersStruct::default()).unwrap();
925
1
        map.populate_from(&EnumVariants::Struct { arg: 1 }).unwrap();
926
1
        map.populate_from(&EnumVariants::Tuple(0)).unwrap();
927
1
        map.populate_from(&EnumVariants::TupleTwoArgs(0, 1))
928
1
            .unwrap();
929
1
        assert_eq!(map.populate_from(&EnumVariants::Unit).unwrap(), 1);
930
1
        assert_eq!(map.populate_from(&EnumVariants::Unit).unwrap(), 0);
931
1
        dbg!(map);
932
1
    }
933

            
934
1
    #[test]
935
1
    fn backwards_compatible() {
936
5
        #[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
937
1
        struct Canary {
938
1
            name: String,
939
1
            id: u64,
940
1
        }
941
1

            
942
1
        let canary = Canary {
943
1
            name: String::from("coalmine"),
944
1
            id: 0xfeed_d0d0_dead_beef,
945
1
        };
946
1

            
947
1
        // This payload was generated with pot 1.0 using the same structure.
948
1
        // This structure should be updated to be more encompassing, but this at
949
1
        // least tests for basic compatibility.
950
1
        let v1_canary = [
951
1
            80, 111, 116, 0, 162, 200, 110, 97, 109, 101, 232, 99, 111, 97, 108, 109, 105, 110,
952
1
            101, 196, 105, 100, 71, 239, 190, 173, 222, 208, 208, 237, 254,
953
1
        ];
954
1
        let parsed: Canary = crate::from_slice(&v1_canary).unwrap();
955
1
        assert_eq!(canary, parsed);
956
1
    }
957
}