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