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}