serdect/
lib.rs

1#![no_std]
2#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(
5    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
6    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
7)]
8#![forbid(unsafe_code)]
9#![warn(
10    clippy::mod_module_files,
11    clippy::unwrap_used,
12    missing_docs,
13    rust_2018_idioms,
14    unused_lifetimes,
15    unused_qualifications
16)]
17
18//! ## Usage
19//!
20//! ### Implementing `Deserialize` and `Serialize` for arrays.
21//!
22#![cfg_attr(feature = "alloc", doc = " ```")]
23#![cfg_attr(not(feature = "alloc"), doc = " ```ignore")]
24//! # use serde::{Deserialize, Deserializer, Serialize, Serializer};
25//! #
26//! # #[derive(Debug, PartialEq)]
27//! struct SecretData([u8; 32]);
28//!
29//! impl<'de> Deserialize<'de> for SecretData {
30//!     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
31//!     where
32//!         D: Deserializer<'de>,
33//!     {
34//!         let mut buffer = [0; 32];
35//!         serdect::array::deserialize_hex_or_bin(&mut buffer, deserializer)?;
36//!         Ok(Self(buffer))
37//!     }
38//! }
39//!
40//! impl Serialize for SecretData {
41//!     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
42//!     where
43//!         S: Serializer,
44//!     {
45//!         serdect::array::serialize_hex_lower_or_bin(&self.0, serializer)
46//!     }
47//! }
48//!
49//! let data = SecretData([42; 32]);
50//!
51//! let serialized = bincode::serialize(&data).unwrap();
52//! // bincode, a binary serialization format, is serialized into bytes.
53//! assert_eq!(serialized.as_slice(), [42; 32]);
54//! # let deserialized: SecretData = bincode::deserialize(&serialized).unwrap();
55//! # assert_eq!(deserialized, data);
56//!
57//! let serialized = serde_json::to_string(&data).unwrap();
58//! // JSON, a human-readable serialization format, is serialized into lower-case HEX.
59//! assert_eq!(
60//!     serialized,
61//!     "\"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a\""
62//! );
63//! # let deserialized: SecretData = serde_json::from_str(&serialized).unwrap();
64//! # assert_eq!(deserialized, data);
65//! ```
66//!
67//! ### Implementing `Deserialize` and `Serialize` for slices.
68//!
69#![cfg_attr(feature = "alloc", doc = " ```")]
70#![cfg_attr(not(feature = "alloc"), doc = " ```ignore")]
71//! # use serde::{Deserialize, Deserializer, Serialize, Serializer};
72//! #
73//! # #[derive(Debug, PartialEq)]
74//! struct SecretData(Vec<u8>);
75//!
76//! impl<'de> Deserialize<'de> for SecretData {
77//!     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
78//!     where
79//!         D: Deserializer<'de>,
80//!     {
81//!         serdect::slice::deserialize_hex_or_bin_vec(deserializer).map(Self)
82//!     }
83//! }
84//!
85//! impl Serialize for SecretData {
86//!     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
87//!     where
88//!         S: Serializer,
89//!     {
90//!         serdect::slice::serialize_hex_lower_or_bin(&self.0, serializer)
91//!     }
92//! }
93//!
94//! let data = SecretData(vec![42; 32]);
95//!
96//! let serialized = bincode::serialize(&data).unwrap();
97//! // bincode, a binary serialization format is serialized into bytes.
98//! assert_eq!(
99//!     serialized.as_slice(),
100//!     [
101//!         // Not fixed-size, so a size will be encoded.
102//!         32, 0, 0, 0, 0, 0, 0, 0,
103//!         // Actual data.
104//!         42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
105//!         42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
106//!     ]
107//! );
108//! # let deserialized: SecretData = bincode::deserialize(&serialized).unwrap();
109//! # assert_eq!(deserialized, data);
110//!
111//! let serialized = serde_json::to_string(&data).unwrap();
112//! // JSON, a human-readable serialization format is serialized into lower-case HEX.
113//! assert_eq!(
114//!     serialized,
115//!     "\"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a\""
116//! );
117//! # let deserialized: SecretData = serde_json::from_str(&serialized).unwrap();
118//! # assert_eq!(deserialized, data);
119//! ```
120
121#[cfg(feature = "alloc")]
122extern crate alloc;
123
124pub mod array;
125pub mod slice;
126
127pub use serde;
128
129use serde::Serializer;
130
131#[cfg(not(feature = "alloc"))]
132use serde::ser::Error;
133
134#[cfg(feature = "alloc")]
135use serde::Serialize;
136
137fn serialize_hex<S, T, const UPPERCASE: bool>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
138where
139    S: Serializer,
140    T: AsRef<[u8]>,
141{
142    #[cfg(feature = "alloc")]
143    if UPPERCASE {
144        return base16ct::upper::encode_string(value.as_ref()).serialize(serializer);
145    } else {
146        return base16ct::lower::encode_string(value.as_ref()).serialize(serializer);
147    }
148    #[cfg(not(feature = "alloc"))]
149    {
150        let _ = value;
151        let _ = serializer;
152        return Err(S::Error::custom(
153            "serializer is human readable, which requires the `alloc` crate feature",
154        ));
155    }
156}