Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support deserializing from borrowed or owned bytes, too #668

Merged
merged 6 commits into from Aug 31, 2022
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
94 changes: 90 additions & 4 deletions primitive-types/impls/serde/src/serialize.rs
Expand Up @@ -187,8 +187,8 @@ pub enum ExpectedLen<'a> {
impl<'a> fmt::Display for ExpectedLen<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
ExpectedLen::Exact(ref v) => write!(fmt, "length of {}", v.len() * 2),
ExpectedLen::Between(min, ref v) => write!(fmt, "length between ({}; {}]", min * 2, v.len() * 2),
ExpectedLen::Exact(ref v) => write!(fmt, "{} bytes", v.len()),
ExpectedLen::Between(min, ref v) => write!(fmt, "between ({}; {}] bytes", min, v.len()),
}
}
}
Expand All @@ -205,7 +205,7 @@ where
type Value = Vec<u8>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a (both 0x-prefixed or not) hex string")
write!(formatter, "a (both 0x-prefixed or not) hex string or byte array")
}

fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
Expand All @@ -215,6 +215,14 @@ where
fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
self.visit_str(&v)
}

fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
Ok(v.to_vec())
}

fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
Ok(v)
}
}

deserializer.deserialize_str(Visitor)
Expand All @@ -234,7 +242,7 @@ where
type Value = usize;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a (both 0x-prefixed or not) hex string with {}", self.len)
write!(formatter, "a (both 0x-prefixed or not) hex string or byte array containing {}", self.len)
}

fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
Expand All @@ -261,6 +269,32 @@ where
fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
self.visit_str(&v)
}

fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
let len = v.len();
let is_len_valid = match self.len {
ExpectedLen::Exact(ref slice) => len == slice.len(),
ExpectedLen::Between(min, ref slice) => len <= slice.len() && len > min,
};

if !is_len_valid {
return Err(E::invalid_length(v.len(), &self))
}

let bytes = match self.len {
ExpectedLen::Exact(slice) => slice,
ExpectedLen::Between(_, slice) => slice,
};

for (index, byte) in v.iter().enumerate() {
bytes[index] = *byte;
}
ordian marked this conversation as resolved.
Show resolved Hide resolved
Ok(len)
}

fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Self::Value, E> {
self.visit_bytes(&v)
}
}

deserializer.deserialize_str(Visitor { len })
Expand Down Expand Up @@ -367,4 +401,56 @@ mod tests {
assert_eq!(from_hex("102"), Ok(vec![1, 2]));
assert_eq!(from_hex("f"), Ok(vec![0xf]));
}

#[test]
fn should_deserialize_from_owned_bytes() {
type BytesDeserializer<'a> = serde::de::value::BytesDeserializer<'a, serde::de::value::Error>;

// using `deserialize` to decode owned bytes.
let des = BytesDeserializer::new(&[1, 2, 3, 4, 5]);
let deserialized: Vec<u8> = deserialize(des).unwrap();
assert_eq!(deserialized, vec![1, 2, 3, 4, 5]);

// using `deserialize` to decode owned bytes into buffer with fixed length.
let des = BytesDeserializer::new(&[1, 2, 3, 4, 5]);
let mut output = vec![0, 0, 0, 0, 0];
let expected_len = ExpectedLen::Exact(&mut *output);
let n = deserialize_check_len(des, expected_len).unwrap();
assert_eq!(n, 5);
assert_eq!(output, vec![1, 2, 3, 4, 5]);

// using `deserialize` to decode owned bytes into buffer with min/max length.
let des = BytesDeserializer::new(&[1, 2, 3]);
let mut output = vec![0, 0, 0, 0, 0];
let expected_len = ExpectedLen::Between(2, &mut *output);
let n = deserialize_check_len(des, expected_len).unwrap();
assert_eq!(n, 3);
assert_eq!(output, vec![1, 2, 3, 0, 0]);
}

#[test]
fn should_deserialize_from_borrowed_bytes() {
type BytesDeserializer<'a> = serde::de::value::BorrowedBytesDeserializer<'a, serde::de::value::Error>;

// using `deserialize` to decode borrowed bytes.
let des = BytesDeserializer::new(&[1, 2, 3, 4, 5]);
let deserialized: Vec<u8> = deserialize(des).unwrap();
assert_eq!(deserialized, vec![1, 2, 3, 4, 5]);

// using `deserialize` to decode borrowed bytes into buffer with fixed length.
let des = BytesDeserializer::new(&[1, 2, 3, 4, 5]);
let mut output = vec![0, 0, 0, 0, 0];
let expected_len = ExpectedLen::Exact(&mut *output);
let n = deserialize_check_len(des, expected_len).unwrap();
assert_eq!(n, 5);
assert_eq!(output, vec![1, 2, 3, 4, 5]);

// using `deserialize` to decode borrowed bytes into buffer with min/max length.
let des = BytesDeserializer::new(&[1, 2, 3]);
let mut output = vec![0, 0, 0, 0, 0];
let expected_len = ExpectedLen::Between(2, &mut *output);
let n = deserialize_check_len(des, expected_len).unwrap();
assert_eq!(n, 3);
assert_eq!(output, vec![1, 2, 3, 0, 0]);
}
}