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

            
16
use std::io::{Read, Write};
17

            
18
use serde::{de::DeserializeOwned, Deserialize, Serialize};
19
pub use serde_json;
20
pub use transmog;
21
use transmog::{BorrowedDeserializer, Format, OwnedDeserializer};
22

            
23
/// Json implementor of [`Format`].
24
2
#[derive(Clone, Default)]
25
#[must_use]
26
pub struct Json {
27
    pretty: bool,
28
}
29

            
30
impl Json {
31
    /// Returns an instance configured to serialize in a "pretty" format.
32
1
    pub fn pretty(mut self) -> Self {
33
1
        self.pretty = true;
34
1
        self
35
1
    }
36
}
37

            
38
impl<'a, T> Format<'a, T> for Json
39
where
40
    T: Serialize,
41
{
42
    type Error = Error;
43

            
44
4
    fn serialize(&self, value: &T) -> Result<Vec<u8>, Self::Error> {
45
4
        if self.pretty {
46
2
            serde_json::to_vec_pretty(value).map_err(Error::from)
47
        } else {
48
2
            serde_json::to_vec(value).map_err(Error::from)
49
        }
50
4
    }
51

            
52
2
    fn serialize_into<W: Write>(&self, value: &T, writer: W) -> Result<(), Self::Error> {
53
2
        if self.pretty {
54
1
            serde_json::to_writer_pretty(writer, value).map_err(Error::from)
55
        } else {
56
1
            serde_json::to_writer(writer, value).map_err(Error::from)
57
        }
58
2
    }
59
}
60

            
61
impl<'a, T> BorrowedDeserializer<'a, T> for Json
62
where
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

            
70
impl<T> OwnedDeserializer<T> for Json
71
where
72
    T: Serialize + DeserializeOwned,
73
{
74
4
    fn deserialize_owned(&self, data: &[u8]) -> Result<T, Self::Error> {
75
4
        serde_json::from_slice(data).map_err(Error::from)
76
4
    }
77
2
    fn deserialize_from<R: Read>(&self, reader: R) -> Result<T, Self::Error> {
78
2
        serde_json::from_reader(reader).map_err(Error::from)
79
2
    }
80
}
81

            
82
1
#[test]
83
1
fn format_tests() {
84
1
    transmog::test_util::test_format(&Json::default());
85
1
    transmog::test_util::test_format(&Json::default().pretty());
86
1
}
87

            
88
/// Errors from [`Json`].
89
2
#[derive(thiserror::Error, Debug)]
90
pub 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
}