Skip to content

Commit

Permalink
serdect: return the deserialized buffer during deserialization (#1515)
Browse files Browse the repository at this point in the history
Fixes #1322
  • Loading branch information
fjarri authored Sep 10, 2024
1 parent 320ee91 commit 816286f
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 14 deletions.
2 changes: 1 addition & 1 deletion serdect/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl LengthCheck for ExactLength {
/// Deserialize from hex when using human-readable formats or binary if the
/// format is binary. Fails if the `buffer` isn't the exact same size as the
/// resulting array.
pub fn deserialize_hex_or_bin<'de, D>(buffer: &mut [u8], deserializer: D) -> Result<(), D::Error>
pub fn deserialize_hex_or_bin<'de, D>(buffer: &mut [u8], deserializer: D) -> Result<&[u8], D::Error>
where
D: Deserializer<'de>,
{
Expand Down
26 changes: 14 additions & 12 deletions serdect/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::fmt;
use core::marker::PhantomData;

use serde::{
de::{Error, Visitor},
de::{Error, Unexpected, Visitor},
Serializer,
};

Expand Down Expand Up @@ -74,7 +74,7 @@ pub(crate) trait LengthCheck {
pub(crate) struct StrIntoBufVisitor<'b, T: LengthCheck>(pub &'b mut [u8], pub PhantomData<T>);

impl<'de, 'b, T: LengthCheck> Visitor<'de> for StrIntoBufVisitor<'b, T> {
type Value = ();
type Value = &'b [u8];

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
T::expecting(formatter, "a string", self.0.len() * 2)
Expand All @@ -84,13 +84,15 @@ impl<'de, 'b, T: LengthCheck> Visitor<'de> for StrIntoBufVisitor<'b, T> {
where
E: Error,
{
if !T::length_check(self.0.len() * 2, v.len()) {
return Err(Error::invalid_length(v.len(), &self));
}
// TODO: Map `base16ct::Error::InvalidLength` to `Error::invalid_length`.
base16ct::mixed::decode(v, self.0)
.map(|_| ())
.map_err(E::custom)
base16ct::mixed::decode(v, self.0).map_err(|err| match err {
base16ct::Error::InvalidLength => {
Error::invalid_length(v.len(), &"an even number of hex digits")
}
base16ct::Error::InvalidEncoding => Error::invalid_value(
Unexpected::Other("<potentially secret hex string>"),
&"a sequence of hex digits (0-9,a-f,A-F)",
),
})
}
}

Expand All @@ -116,7 +118,7 @@ impl<'de> Visitor<'de> for StrIntoVecVisitor {
pub(crate) struct SliceVisitor<'b, T: LengthCheck>(pub &'b mut [u8], pub PhantomData<T>);

impl<'de, 'b, T: LengthCheck> Visitor<'de> for SliceVisitor<'b, T> {
type Value = ();
type Value = &'b [u8];

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
T::expecting(formatter, "an array", self.0.len())
Expand All @@ -131,7 +133,7 @@ impl<'de, 'b, T: LengthCheck> Visitor<'de> for SliceVisitor<'b, T> {
if T::length_check(self.0.len(), v.len()) {
let buffer = &mut self.0[..v.len()];
buffer.copy_from_slice(v);
return Ok(());
return Ok(buffer);
}

Err(E::invalid_length(v.len(), &self))
Expand All @@ -147,7 +149,7 @@ impl<'de, 'b, T: LengthCheck> Visitor<'de> for SliceVisitor<'b, T> {
if T::length_check(self.0.len(), v.len()) {
let buffer = &mut self.0[..v.len()];
buffer.swap_with_slice(&mut v);
return Ok(());
return Ok(buffer);
}

Err(E::invalid_length(v.len(), &self))
Expand Down
2 changes: 1 addition & 1 deletion serdect/src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl LengthCheck for UpperBound {
/// Deserialize from hex when using human-readable formats or binary if the
/// format is binary. Fails if the `buffer` is smaller then the resulting
/// slice.
pub fn deserialize_hex_or_bin<'de, D>(buffer: &mut [u8], deserializer: D) -> Result<(), D::Error>
pub fn deserialize_hex_or_bin<'de, D>(buffer: &mut [u8], deserializer: D) -> Result<&[u8], D::Error>
where
D: Deserializer<'de>,
{
Expand Down

0 comments on commit 816286f

Please sign in to comment.