transmog_json/
lib.rs

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)]
15
16use std::io::{Read, Write};
17
18use serde::{de::DeserializeOwned, Deserialize, Serialize};
19pub use serde_json;
20pub use transmog;
21use transmog::{BorrowedDeserializer, Format, OwnedDeserializer};
22
23/// Json implementor of [`Format`].
24#[derive(Clone, Default)]
25#[must_use]
26pub struct Json {
27    pretty: bool,
28}
29
30impl Json {
31    /// Returns an instance configured to serialize in a "pretty" format.
32    pub fn pretty(mut self) -> Self {
33        self.pretty = true;
34        self
35    }
36}
37
38impl<'a, T> Format<'a, T> for Json
39where
40    T: Serialize,
41{
42    type Error = Error;
43
44    fn serialize(&self, value: &T) -> Result<Vec<u8>, Self::Error> {
45        if self.pretty {
46            serde_json::to_vec_pretty(value).map_err(Error::from)
47        } else {
48            serde_json::to_vec(value).map_err(Error::from)
49        }
50    }
51
52    fn serialize_into<W: Write>(&self, value: &T, writer: W) -> Result<(), Self::Error> {
53        if self.pretty {
54            serde_json::to_writer_pretty(writer, value).map_err(Error::from)
55        } else {
56            serde_json::to_writer(writer, value).map_err(Error::from)
57        }
58    }
59}
60
61impl<'a, T> BorrowedDeserializer<'a, T> for Json
62where
63    T: Serialize + Deserialize<'a>,
64{
65    fn deserialize_borrowed(&self, data: &'a [u8]) -> Result<T, Self::Error> {
66        serde_json::from_slice(data).map_err(Error::from)
67    }
68}
69
70impl<T> OwnedDeserializer<T> for Json
71where
72    T: Serialize + DeserializeOwned,
73{
74    fn deserialize_owned(&self, data: &[u8]) -> Result<T, Self::Error> {
75        serde_json::from_slice(data).map_err(Error::from)
76    }
77    fn deserialize_from<R: Read>(&self, reader: R) -> Result<T, Self::Error> {
78        serde_json::from_reader(reader).map_err(Error::from)
79    }
80}
81
82#[test]
83fn format_tests() {
84    transmog::test_util::test_format(&Json::default());
85    transmog::test_util::test_format(&Json::default().pretty());
86}
87
88/// Errors from [`Json`].
89#[derive(thiserror::Error, Debug)]
90pub enum Error {
91    /// An error occurred from parsing `Json`.
92    #[error("json error: {0}")]
93    Json(#[from] serde_json::Error),
94    /// An Io error occurred outside of parsing `Json`.
95    #[error("io error: {0}")]
96    Io(#[from] std::io::Error),
97}