mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-11 22:01:04 +00:00
Merge pull request #72 from borman/bytestrings
Improved support for byte strings
This commit is contained in:
@@ -686,6 +686,16 @@ fn deserialize_field_visitor(
|
|||||||
{
|
{
|
||||||
$body
|
$body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(&mut self, value: &[u8]) -> ::std::result::Result<__Field, E>
|
||||||
|
where E: ::serde::de::Error,
|
||||||
|
{
|
||||||
|
// TODO: would be better to generate a byte string literal match
|
||||||
|
match ::std::str::from_utf8(value) {
|
||||||
|
Ok(s) => self.visit_str(s),
|
||||||
|
_ => Err(::serde::de::Error::syntax_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.visit(
|
deserializer.visit(
|
||||||
|
|||||||
+43
-4
@@ -1,6 +1,8 @@
|
|||||||
//! Helper module to enable serializing bytes more efficiently
|
//! Helper module to enable serializing bytes more efficiently
|
||||||
|
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
use std::fmt;
|
||||||
|
use std::ascii;
|
||||||
|
|
||||||
use ser;
|
use ser;
|
||||||
use de;
|
use de;
|
||||||
@@ -8,10 +10,17 @@ use de;
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// `Bytes` wraps a `&[u8]` in order to serialize into a byte array.
|
/// `Bytes` wraps a `&[u8]` in order to serialize into a byte array.
|
||||||
|
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Bytes<'a> {
|
pub struct Bytes<'a> {
|
||||||
bytes: &'a [u8],
|
bytes: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> fmt::Debug for Bytes<'a> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "b\"{}\"", escape_bytestring(self.bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [u8]> for Bytes<'a> {
|
impl<'a> From<&'a [u8]> for Bytes<'a> {
|
||||||
fn from(bytes: &'a [u8]) -> Self {
|
fn from(bytes: &'a [u8]) -> Self {
|
||||||
Bytes {
|
Bytes {
|
||||||
@@ -28,6 +37,12 @@ impl<'a> From<&'a Vec<u8>> for Bytes<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Into<&'a [u8]> for Bytes<'a> {
|
||||||
|
fn into(self) -> &'a [u8] {
|
||||||
|
self.bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ops::Deref for Bytes<'a> {
|
impl<'a> ops::Deref for Bytes<'a> {
|
||||||
type Target = [u8];
|
type Target = [u8];
|
||||||
|
|
||||||
@@ -46,7 +61,7 @@ impl<'a> ser::Serialize for Bytes<'a> {
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
|
/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
|
||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct ByteBuf {
|
pub struct ByteBuf {
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
}
|
}
|
||||||
@@ -65,10 +80,22 @@ impl ByteBuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<T> for ByteBuf where T: Into<Vec<u8>> {
|
impl fmt::Debug for ByteBuf {
|
||||||
fn from(bytes: T) -> Self {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Vec<u8>> for ByteBuf {
|
||||||
|
fn into(self) -> Vec<u8> {
|
||||||
|
self.bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<u8>> for ByteBuf {
|
||||||
|
fn from(bytes: Vec<u8>) -> Self {
|
||||||
ByteBuf {
|
ByteBuf {
|
||||||
bytes: bytes.into(),
|
bytes: bytes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,3 +199,15 @@ impl de::Deserialize for ByteBuf {
|
|||||||
deserializer.visit_bytes(ByteBufVisitor)
|
deserializer.visit_bytes(ByteBufVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
fn escape_bytestring(bytes: &[u8]) -> String {
|
||||||
|
let mut result = String::new();
|
||||||
|
for &b in bytes {
|
||||||
|
for esc in ascii::escape_default(b) {
|
||||||
|
result.push(esc as char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::hash::Hash;
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::path;
|
use std::path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::str;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
@@ -216,6 +217,24 @@ impl Visitor for StringVisitor {
|
|||||||
{
|
{
|
||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<String, E>
|
||||||
|
where E: Error,
|
||||||
|
{
|
||||||
|
match str::from_utf8(v) {
|
||||||
|
Ok(s) => Ok(s.to_string()),
|
||||||
|
Err(_) => Err(Error::syntax_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_byte_buf<'a, E>(&mut self, v: Vec<u8>) -> Result<String, E>
|
||||||
|
where E: Error,
|
||||||
|
{
|
||||||
|
match String::from_utf8(v) {
|
||||||
|
Ok(s) => Ok(s),
|
||||||
|
Err(_) => Err(Error::syntax_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deserialize for String {
|
impl Deserialize for String {
|
||||||
|
|||||||
+2
-2
@@ -272,10 +272,10 @@ pub trait Visitor {
|
|||||||
Err(Error::syntax_error())
|
Err(Error::syntax_error())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_byte_buf<E>(&mut self, _v: Vec<u8>) -> Result<Self::Value, E>
|
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||||
where E: Error,
|
where E: Error,
|
||||||
{
|
{
|
||||||
Err(Error::syntax_error())
|
self.visit_bytes(&v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use std::hash::Hash;
|
|||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
use de;
|
use de;
|
||||||
|
use bytes;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -409,3 +410,56 @@ impl<K, V> ValueDeserializer for HashMap<K, V>
|
|||||||
MapDeserializer::new(self.into_iter(), len)
|
MapDeserializer::new(self.into_iter(), len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl<'a> ValueDeserializer for bytes::Bytes<'a>
|
||||||
|
{
|
||||||
|
type Deserializer = BytesDeserializer<'a>;
|
||||||
|
|
||||||
|
fn into_deserializer(self) -> BytesDeserializer<'a> {
|
||||||
|
BytesDeserializer(Some(self.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BytesDeserializer<'a> (Option<&'a [u8]>);
|
||||||
|
|
||||||
|
impl<'a> de::Deserializer for BytesDeserializer<'a> {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
|
match self.0.take() {
|
||||||
|
Some(bytes) => visitor.visit_bytes(bytes),
|
||||||
|
None => Err(de::Error::end_of_stream_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl ValueDeserializer for bytes::ByteBuf
|
||||||
|
{
|
||||||
|
type Deserializer = ByteBufDeserializer;
|
||||||
|
|
||||||
|
fn into_deserializer(self) -> Self::Deserializer {
|
||||||
|
ByteBufDeserializer(Some(self.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ByteBufDeserializer(Option<Vec<u8>>);
|
||||||
|
|
||||||
|
impl de::Deserializer for ByteBufDeserializer {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: de::Visitor,
|
||||||
|
{
|
||||||
|
match self.0.take() {
|
||||||
|
Some(bytes) => visitor.visit_byte_buf(bytes),
|
||||||
|
None => Err(de::Error::end_of_stream_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user