musli/storage/
encoding.rs

1//! Module that defines [`Encoding`] whith allows for customization of the
2//! encoding format, and the [`DEFAULT`] encoding configuration.
3
4use core::marker;
5
6use crate::mode::Binary;
7use crate::options;
8use crate::{IntoReader, Options};
9
10use super::de::StorageDecoder;
11use super::en::StorageEncoder;
12use super::error::Error;
13
14/// Default options to use with [`Encoding`].
15pub const OPTIONS: Options = options::new().build();
16
17/// The default configuration.
18///
19/// Uses variable-encoded numerical fields and variable-encoded prefix lengths.
20///
21/// The variable length encoding uses [`zigzag`] with [`variable length`]
22/// encoding for numbers.
23///
24/// [`zigzag`]: https://en.wikipedia.org/wiki/Variable-length_quantity#Zigzag_encoding
25/// [`variable length`]: https://en.wikipedia.org/wiki/Variable-length_quantity
26pub const DEFAULT: Encoding = Encoding::new();
27
28crate::macros::bare_encoding!(Binary, DEFAULT, storage, IntoReader);
29
30/// Setting up encoding with parameters.
31pub struct Encoding<const OPT: Options = OPTIONS, M = Binary>
32where
33    M: 'static,
34{
35    _marker: marker::PhantomData<M>,
36}
37
38impl Default for Encoding<OPTIONS, Binary> {
39    #[inline]
40    fn default() -> Self {
41        Self::new()
42    }
43}
44
45impl Encoding<OPTIONS, Binary> {
46    /// Construct a new [`Encoding`] instance which uses [`OPTIONS`].
47    ///
48    /// You can modify this behavior by using a custom [`Options`] instance:
49    ///
50    /// ```
51    /// use musli::{Encode, Decode};
52    /// use musli::options::{self, Options, Integer};
53    /// use musli::storage::Encoding;
54    /// # use musli::storage::Error;
55    ///
56    /// const OPTIONS: Options = options::new().with_integer(Integer::Fixed).build();
57    /// const CONFIG: Encoding<OPTIONS> = Encoding::new().with_options();
58    ///
59    /// #[derive(Debug, PartialEq, Encode, Decode)]
60    /// struct Person<'a> {
61    ///     name: &'a str,
62    ///     age: u32,
63    /// }
64    ///
65    /// let mut out = Vec::new();
66    ///
67    /// let expected = Person {
68    ///     name: "Aristotle",
69    ///     age: 61,
70    /// };
71    ///
72    /// CONFIG.encode(&mut out, &expected)?;
73    /// let actual = CONFIG.decode(&out[..])?;
74    ///
75    /// assert_eq!(expected, actual);
76    /// # Ok::<_, Error>(())
77    /// ```
78    pub const fn new() -> Self {
79        Encoding {
80            _marker: marker::PhantomData,
81        }
82    }
83}
84
85impl<const OPT: Options, M> Encoding<OPT, M>
86where
87    M: 'static,
88{
89    /// Change the mode of the encoding.
90    ///
91    /// # Examples
92    ///
93    /// ```rust
94    /// use musli::storage::{OPTIONS, Encoding};
95    ///
96    /// enum Custom {}
97    ///
98    /// const CONFIG: Encoding<OPTIONS, Custom> = Encoding::new().with_mode();
99    /// ```
100    pub const fn with_mode<T>(self) -> Encoding<OPT, T> {
101        Encoding {
102            _marker: marker::PhantomData,
103        }
104    }
105
106    /// Change the options of the encoding.
107    ///
108    /// # Examples
109    ///
110    /// ```
111    /// use musli::options::{self, Options, Integer};
112    /// use musli::storage::Encoding;
113    ///
114    /// const OPTIONS: Options = options::new().with_integer(Integer::Fixed).build();
115    /// const CONFIG: Encoding<OPTIONS> = Encoding::new().with_options();
116    /// ```
117    pub const fn with_options<const U: Options>(self) -> Encoding<U, M> {
118        Encoding {
119            _marker: marker::PhantomData,
120        }
121    }
122
123    crate::macros::encoding_impls!(
124        M,
125        storage,
126        StorageEncoder::<_, OPT, _>::new,
127        StorageDecoder::<_, OPT, _>::new,
128        IntoReader::into_reader,
129    );
130}
131
132impl<const OPT: Options, M> Clone for Encoding<OPT, M> {
133    #[inline]
134    fn clone(&self) -> Self {
135        *self
136    }
137}
138
139impl<const OPT: Options, M> Copy for Encoding<OPT, M> {}