Skip to main content

koit_toml/
format.rs

1//! Formats handle transforming structured data to and from bytes for persisting.
2
3/// Trait implementable by format providers.
4///
5/// By implementing this trait, a type becomes a marker for the specified format.
6/// That type can then be used for formatting (without instantiating an object of that type).
7pub trait Format<T>: Sized {
8  type SerError: std::error::Error + Send + Sync + 'static;
9  type DeError: std::error::Error + Send + Sync + 'static;
10
11  /// Convert data to bytes.
12  ///
13  /// # Errors
14  ///
15  /// If the data failed to be encoded by the format, an error variant is returned.
16  fn to_bytes(value: &T) -> Result<Vec<u8>, Self::SerError>;
17
18  /// Convert bytes to data.
19  ///
20  /// # Errors
21  ///
22  /// If the bytes failed to be decoded by the format, an error variant is returned.
23  fn from_bytes(data: Vec<u8>) -> Result<T, Self::DeError>;
24}
25
26#[cfg(feature = "json-format")]
27pub use self::json::Json;
28
29#[cfg(feature = "json-format")]
30mod json {
31  use serde::{de::DeserializeOwned, Serialize};
32
33  use super::Format;
34
35  #[cfg_attr(docsrs, doc(cfg(feature = "json-format")))]
36  /// A pretty-printed JSON [`Format`](crate::format::Format).
37  #[derive(Debug, std::default::Default)]
38  pub struct Json;
39
40  impl<T: DeserializeOwned + Serialize> Format<T> for Json {
41    type DeError = serde_json::Error;
42    type SerError = Self::DeError;
43
44    fn to_bytes(value: &T) -> Result<Vec<u8>, Self::SerError> {
45      serde_json::to_vec_pretty(value)
46    }
47    fn from_bytes(data: Vec<u8>) -> Result<T, Self::DeError> {
48      serde_json::from_slice(&data)
49    }
50  }
51}
52
53#[cfg(feature = "bincode-format")]
54pub use self::bincode::Bincode;
55
56#[cfg(feature = "bincode-format")]
57mod bincode {
58  use serde::{de::DeserializeOwned, Serialize};
59
60  use super::Format;
61
62  #[cfg_attr(docsrs, doc(cfg(feature = "bincode-format")))]
63  /// A Bincode [`Format`](crate::format::Format).
64  #[derive(Debug, std::default::Default)]
65  pub struct Bincode;
66
67  impl<T: Serialize + DeserializeOwned> Format<T> for Bincode {
68    type DeError = bincode::Error;
69    type SerError = Self::DeError;
70
71    fn to_bytes(value: &T) -> Result<Vec<u8>, Self::SerError> {
72      bincode::serialize(value)
73    }
74    fn from_bytes(data: Vec<u8>) -> Result<T, Self::DeError> {
75      bincode::deserialize(&data)
76    }
77  }
78}
79
80#[cfg(feature = "toml-format")]
81pub use self::toml::Toml;
82
83#[cfg(feature = "toml-format")]
84mod toml {
85  use serde::{de::DeserializeOwned, Serialize};
86
87  use super::Format;
88
89  #[cfg_attr(docsrs, doc(cfg(feature = "toml-format")))]
90  /// A pretty-printed Toml [`Format`](crate::format::Format).
91  #[derive(Debug, std::default::Default)]
92  pub struct Toml;
93
94  impl<T: DeserializeOwned + Serialize> Format<T> for Toml {
95    type SerError = toml::ser::Error;
96    type DeError = toml::de::Error;
97
98    fn to_bytes(value: &T) -> Result<Vec<u8>, Self::SerError> {
99      toml::to_vec(value)
100    }
101    fn from_bytes(data: Vec<u8>) -> Result<T, Self::DeError> {
102      toml::from_slice(&data)
103    }
104  }
105}