Skip to content

Commit ee27254

Browse files
committed
Implement serde as bytes for GenericArray<u8, N>
1 parent 8377e2e commit ee27254

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

PR.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
What's this?
2+
- new type `ByteBuf` that is a `Vec<u8, N>` with different / more efficient serde (as bytes). Inherits most functionality via its Deref to Vec.
3+
- some additional methods (into_vec, to_vec, try_to_vec,... from_writer, insert, remove, insert_slice_at, resize_to_capacity, inherent as_slice/as_mut_slice, etc.)
4+
- wrapper types allowing one to perform efficient serde on slices and byte vectors without using the ByteBuf type
5+
- addition of some uDebug implementations, dependency on `ufmt` instead of `ufmt-write` (otherwise there would be too many cargo features)
6+
7+
This is a melange of existing `heapless`, `serde_bytes` and `std` code. I've found it very useful to have a standard "extendable bytes" type (merging [u8; N] and Vec<u8, N>), so I believe this is also of independent interest as shared type.
8+
9+
I left out the `Bytes` type from `serde_bytes` as I've found no use for it; could be added.
10+
11+
I would prefer using the name Bytes for ByteBuf, but I think that would be confusing to anyone used to the `serde_bytes` ByteBuf.
12+
13+
MSRV: `insert_slice_at` would profit from `copy_within`, which stabilised in 1.37 while the MSRV is 1.36. I assume we don't want to bump the MSRV.
14+

src/serde_as_bytes/de.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::{fmt, marker};
22

3-
use generic_array::ArrayLength;
3+
use generic_array::{ArrayLength, GenericArray};
44
use serde::Deserializer;
55
use serde::de::{Error, Visitor};
66

@@ -24,6 +24,41 @@ impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] {
2424
}
2525
}
2626

27+
impl<'de, N> Deserialize<'de> for GenericArray<u8, N>
28+
where
29+
N: ArrayLength<u8>,
30+
{
31+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
32+
where
33+
D: Deserializer<'de>,
34+
{
35+
struct ValueVisitor<'de, N>(marker::PhantomData<(&'de (), N)>);
36+
37+
impl<'de, N> serde::de::Visitor<'de> for ValueVisitor<'de, N>
38+
where
39+
N: ArrayLength<u8>,
40+
{
41+
type Value = GenericArray<u8, N>;
42+
43+
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
44+
formatter.write_str("a sequence")
45+
}
46+
47+
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
48+
where
49+
E: serde::de::Error,
50+
{
51+
if v.len() > N::to_usize() {
52+
return Err(E::invalid_length(v.len(), &self))?;
53+
}
54+
Ok(GenericArray::clone_from_slice(v))
55+
}
56+
}
57+
58+
deserializer.deserialize_bytes(ValueVisitor(marker::PhantomData))
59+
}
60+
}
61+
2762
impl<'de, N> Deserialize<'de> for Vec<u8, N>
2863
where
2964
N: ArrayLength<u8>,

src/serde_as_bytes/ser.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ impl Serialize for [u8] {
1818
}
1919
}
2020

21+
impl<N> Serialize for generic_array::GenericArray<u8, N>
22+
where
23+
N: ArrayLength<u8>
24+
{
25+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
26+
where
27+
S: Serializer,
28+
{
29+
serializer.serialize_bytes(self.as_slice())
30+
}
31+
}
32+
2133
impl<N> Serialize for crate::Vec<u8, N>
2234
where
2335
N: ArrayLength<u8>

0 commit comments

Comments
 (0)