Skip to content

Commit

Permalink
Lenient byte and string deserialization from buffered content
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Apr 19, 2018
1 parent 184264e commit 3c4961c
Show file tree
Hide file tree
Showing 3 changed files with 352 additions and 0 deletions.
10 changes: 10 additions & 0 deletions serde/src/private/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,8 @@ mod content {
match self.content {
Content::String(v) => visitor.visit_string(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(v) => visitor.visit_byte_buf(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand All @@ -1261,8 +1263,11 @@ mod content {
V: Visitor<'de>,
{
match self.content {
Content::String(v) => visitor.visit_string(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(v) => visitor.visit_byte_buf(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::Seq(v) => visit_content_seq(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand Down Expand Up @@ -1966,6 +1971,8 @@ mod content {
match *self.content {
Content::String(ref v) => visitor.visit_str(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(ref v) => visitor.visit_bytes(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand All @@ -1982,8 +1989,11 @@ mod content {
V: Visitor<'de>,
{
match *self.content {
Content::String(ref v) => visitor.visit_str(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(ref v) => visitor.visit_bytes(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::Seq(ref v) => visit_content_seq_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand Down
52 changes: 52 additions & 0 deletions test_suite/tests/bytes/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use serde::de::{Deserializer, Visitor, SeqAccess, Error};
use std::fmt;

pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where D: Deserializer<'de>
{
deserializer.deserialize_byte_buf(ByteBufVisitor)
}

struct ByteBufVisitor;

impl<'de> Visitor<'de> for ByteBufVisitor {
type Value = Vec<u8>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("byte array")
}

fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where V: SeqAccess<'de>
{
let mut values = Vec::new();
while let Some(value) = try!(visitor.next_element()) {
values.push(value);
}
Ok(values)
}

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

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

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where E: Error
{
Ok(v.as_bytes().to_vec())
}

fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where E: Error
{
Ok(v.into_bytes())
}
}

0 comments on commit 3c4961c

Please sign in to comment.