Skip to main content

serde_human_bytes/
ser.rs

1use crate::codec::{Codec, LowerHex};
2use crate::{ByteArray, ByteBuf, Bytes};
3use alloc::borrow::Cow;
4use alloc::boxed::Box;
5use alloc::vec::Vec;
6use serde::Serializer;
7
8pub(crate) fn serialize_bytes<S, C>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
9where
10    S: Serializer,
11    C: Codec,
12{
13    if serializer.is_human_readable() {
14        serializer.serialize_str(&C::encode(bytes))
15    } else {
16        serializer.serialize_bytes(bytes)
17    }
18}
19
20/// Types that can be serialized via `#[serde(with = "serde_human_bytes")]`.
21///
22/// Parameterized by `C: Codec` — the encoding strategy used in human-readable
23/// mode. Defaults to [`LowerHex`](crate::LowerHex) for source-compatibility
24/// with the original (un-parameterized) trait.
25pub trait Serialize<C: Codec = LowerHex> {
26    #[allow(missing_docs)]
27    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
28    where
29        S: Serializer;
30}
31
32impl<C: Codec> Serialize<C> for [u8] {
33    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
34    where
35        S: Serializer,
36    {
37        serialize_bytes::<S, C>(self, serializer)
38    }
39}
40
41impl<C: Codec> Serialize<C> for Vec<u8> {
42    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
43    where
44        S: Serializer,
45    {
46        serialize_bytes::<S, C>(self, serializer)
47    }
48}
49
50impl<C: Codec> Serialize<C> for Bytes {
51    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52    where
53        S: Serializer,
54    {
55        serialize_bytes::<S, C>(self, serializer)
56    }
57}
58
59impl<C: Codec, const N: usize> Serialize<C> for [u8; N] {
60    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
61    where
62        S: Serializer,
63    {
64        serialize_bytes::<S, C>(self, serializer)
65    }
66}
67
68impl<C: Codec, const N: usize> Serialize<C> for ByteArray<N> {
69    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70    where
71        S: Serializer,
72    {
73        serialize_bytes::<S, C>(&**self, serializer)
74    }
75}
76
77impl<C: Codec> Serialize<C> for ByteBuf {
78    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
79    where
80        S: Serializer,
81    {
82        serialize_bytes::<S, C>(self, serializer)
83    }
84}
85
86impl<'a, C: Codec> Serialize<C> for Cow<'a, [u8]> {
87    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
88    where
89        S: Serializer,
90    {
91        serialize_bytes::<S, C>(self, serializer)
92    }
93}
94
95impl<'a, C: Codec> Serialize<C> for Cow<'a, Bytes> {
96    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
97    where
98        S: Serializer,
99    {
100        serialize_bytes::<S, C>(self, serializer)
101    }
102}
103
104impl<T, C: Codec> Serialize<C> for &T
105where
106    T: ?Sized + Serialize<C>,
107{
108    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
109    where
110        S: Serializer,
111    {
112        (**self).serialize(serializer)
113    }
114}
115
116impl<T, C: Codec> Serialize<C> for Box<T>
117where
118    T: ?Sized + Serialize<C>,
119{
120    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
121    where
122        S: Serializer,
123    {
124        (**self).serialize(serializer)
125    }
126}
127
128impl<T, C: Codec> Serialize<C> for Option<T>
129where
130    T: Serialize<C>,
131{
132    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
133    where
134        S: Serializer,
135    {
136        struct AsBytes<T, C>(T, core::marker::PhantomData<C>);
137
138        impl<T, C> serde::Serialize for AsBytes<&T, C>
139        where
140            T: ?Sized + Serialize<C>,
141            C: Codec,
142        {
143            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
144            where
145                S: Serializer,
146            {
147                self.0.serialize(serializer)
148            }
149        }
150
151        match self {
152            Some(b) => serializer.serialize_some(&AsBytes::<&T, C>(b, core::marker::PhantomData)),
153            None => serializer.serialize_none(),
154        }
155    }
156}