musli/storage/
encoding.rs

1use core::marker;
2
3#[cfg(feature = "alloc")]
4use crate::alloc::System;
5use crate::mode::Binary;
6use crate::options;
7use crate::{Context, Decode, Encode, IntoReader, IntoWriter, Options};
8
9use super::de::StorageDecoder;
10use super::en::StorageEncoder;
11#[cfg(feature = "alloc")]
12use super::error::Error;
13
14/// The default options for the storage encoding.
15///
16/// Uses variable-encoded numerical fields and variable-encoded prefix lengths.
17///
18/// The variable length encoding uses [`zigzag`] with [`variable length`]
19/// encoding for numbers.
20///
21/// [`zigzag`]: https://en.wikipedia.org/wiki/Variable-length_quantity#Zigzag_encoding
22/// [`variable length`]: https://en.wikipedia.org/wiki/Variable-length_quantity
23pub const OPTIONS: Options = options::new().build();
24
25#[allow(unused)]
26const DEFAULT: Encoding = Encoding::new();
27
28crate::macros::bare_encoding!(Binary, DEFAULT, storage, IntoReader, IntoWriter);
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().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().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, false, _, _, M>::new,
127        StorageDecoder::<OPT, false, _, _, M>::new,
128        IntoReader::into_reader,
129        IntoWriter::into_writer,
130    );
131}
132
133impl<const OPT: Options, M> Clone for Encoding<OPT, M> {
134    #[inline]
135    fn clone(&self) -> Self {
136        *self
137    }
138}
139
140impl<const OPT: Options, M> Copy for Encoding<OPT, M> {}