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
132
pub fn from_slice<'a, T>(serialized: &'a [u8]) -> Result<T>
83
132
where
84
132
    T: Deserialize<'a>,
85
132
{
86
132
    Config::default().deserialize(serialized)
87
132
}
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
    compatibility: Compatibility,
112
}
113

            
114
impl Default for Config {
115
    #[inline]
116
1349
    fn default() -> Self {
117
1349
        Self::new()
118
1349
    }
119
}
120

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

            
142
    /// Sets the compatibility mode for serializing and returns self.
143
2
    pub const fn compatibility(mut self, compatibilty: Compatibility) -> Self {
144
2
        self.compatibility = compatibilty;
145
2
        self
146
2
    }
147

            
148
    /// Deserializes a value from a slice using the configured options.
149
    #[inline]
150
137
    pub fn deserialize<'de, T>(&self, serialized: &'de [u8]) -> Result<T>
151
137
    where
152
137
        T: Deserialize<'de>,
153
137
    {
154
137
        let mut deserializer = de::Deserializer::from_slice(serialized, self.allocation_budget)?;
155
136
        let t = T::deserialize(&mut deserializer)?;
156
125
        if deserializer.end_of_input() {
157
125
            Ok(t)
158
        } else {
159
            Err(Error::TrailingBytes)
160
        }
161
137
    }
162

            
163
    /// Deserializes a value from a [`Read`] implementer using the configured
164
    /// options.
165
    #[inline]
166
58
    pub fn deserialize_from<T, R: Read>(&self, reader: R) -> Result<T>
167
58
    where
168
58
        T: DeserializeOwned,
169
58
    {
170
58
        let mut deserializer = de::Deserializer::from_read(
171
58
            IoReader::new(reader),
172
58
            SymbolMapRef::temporary(),
173
58
            self.allocation_budget,
174
58
        )?;
175
58
        T::deserialize(&mut deserializer)
176
58
    }
177

            
178
    /// Serializes a value to a `Vec` using the configured options.
179
    #[inline]
180
1097
    pub fn serialize<T: Serialize>(&self, value: &T) -> Result<Vec<u8>> {
181
1097
        let mut output = Vec::new();
182
1097
        self.serialize_into(value, &mut output)?;
183
1097
        Ok(output)
184
1097
    }
185

            
186
    /// Serializes a value to a writer using the configured options.
187
    #[allow(clippy::unused_self)]
188
    #[inline]
189
1156
    pub fn serialize_into<T, W>(&self, value: &T, writer: W) -> Result<()>
190
1156
    where
191
1156
        T: Serialize,
192
1156
        W: WriteBytesExt,
193
1156
    {
194
1156
        let mut serializer = ser::Serializer::new_with_compatibility(writer, self.compatibility)?;
195
1156
        value.serialize(&mut serializer)
196
1156
    }
197
}
198

            
199
/// Compatibility settings for Pot.
200
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
201
#[non_exhaustive]
202
pub enum Compatibility {
203
    /// Serializes data that is compatible with all versions of Pot
204
    /// deserializers.
205
    ///
206
    /// This format does not support [`Value`](crate::Value) deserialization of
207
    /// enum variants without associated data. See [`V5`](Self::V5) for more
208
    /// information.
209
    Full,
210
    /// Serializes data in the default format
211
    ///
212
    /// This format has a single change in how enum variants without associated
213
    /// data are serialized. This change allows `deserialize_any` to
214
    /// unambiguously distinguish between variants with associated data and
215
    /// variants without associated data.
216
    ///
217
    /// This will be the default compatibility setting in `v4.0` and later. All
218
    /// versions after `v3.0.1` are able to read this updated format.
219
    V4,
220
}
221

            
222
impl Compatibility {
223
4404
    const fn const_default() -> Self {
224
4404
        Self::Full
225
4404
    }
226
}
227

            
228
impl Default for Compatibility {
229
1
    fn default() -> Self {
230
1
        Self::const_default()
231
1
    }
232
}
233

            
234
#[cfg(test)]
235
mod tests;