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}