serialization/
deserialize.rs

1//! Provides all deserialisation related methods and their respective formats.
2use crate::Deserialize;
3use crate::error::SerializationError;
4use crate::format::SerializationFormat;
5use anyhow::Error;
6
7/// Shorthand for `Result<T, SerializationError>`.
8type Result<T> = std::result::Result<T, SerializationError>;
9
10/// Attempts to deserialise `subject` using `format` into `T`.
11///
12/// # Arguments
13///
14/// * `subject`: The `Vec<u8>` that represents `T` in binary format.
15/// * `format`: The format to use when deserialising `subject`.
16///
17/// returns: `Result<T>`
18///
19/// # Errors
20/// This method returns a [`SerializationError`] if any of the steps for deserialization fails.
21/// See [`SerializationError`] for specific details on each error scenario.
22///
23/// # Examples
24///
25/// ```
26/// # use serde::*;
27/// # use serialization::*;
28///
29/// # #[derive(Serialize, Deserialize)]
30/// # struct Foo {
31/// #     bar: String,
32/// # }
33///
34/// # fn main() -> anyhow::Result<()> {
35/// let json = b"{ \"bar\": \"baz\" }";
36/// deserialize::<Foo>(json, &SerializationFormat::JSON)?;
37/// #     Ok(())
38/// # }
39#[inline]
40pub fn deserialize<'a, T>(subject: &'a [u8], format: &SerializationFormat) -> Result<T>
41where
42    T: Deserialize<'a>,
43{
44    match format {
45        SerializationFormat::JSON => deserialize_json(subject),
46        SerializationFormat::MessagePack => deserialize_messagepack(subject),
47        SerializationFormat::Toml => deserialize_toml(subject),
48    }
49}
50
51/// Attempts to deserialize `subject` using JSON.
52#[allow(clippy::missing_errors_doc)]
53pub fn deserialize_json<'a, T: Deserialize<'a>>(subject: &'a [u8]) -> Result<T> {
54    serde_json::from_slice(subject)
55        .map_err(|error| SerializationError::Deserialize(Error::from(error)))
56}
57
58/// Attempts to deserialize `subject` using [MessagePack](https://msgpack.org/).
59#[allow(clippy::missing_errors_doc)]
60#[cfg_attr(not(feature = "msgpack"), allow(unused_variables))]
61pub fn deserialize_messagepack<'a, T: Deserialize<'a>>(subject: &'a [u8]) -> Result<T> {
62    #[cfg(not(feature = "msgpack"))]
63    return Err(SerializationError::FormatUnavailable("msgpack"));
64
65    #[cfg(feature = "msgpack")]
66    rmp_serde::from_slice(subject)
67        .map_err(|error| SerializationError::Deserialize(Error::from(error)))
68}
69
70/// Attempts to deserialize `subject` using [TOML](https://toml.io/).
71#[allow(clippy::missing_errors_doc)]
72#[cfg_attr(not(feature = "toml"), allow(unused_variables))]
73pub fn deserialize_toml<'a, T>(subject: &'a [u8]) -> Result<T>
74where
75    T: Deserialize<'a>,
76{
77    #[cfg(not(feature = "toml"))]
78    return Err(SerializationError::FormatUnavailable("toml"));
79
80    #[cfg(feature = "toml")]
81    {
82        let str = String::from_utf8_lossy(subject);
83        let deserializer = toml::Deserializer::new(&str);
84
85        T::deserialize(deserializer)
86            .map_err(|error| SerializationError::Deserialize(Error::from(error)))
87    }
88}