mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-23 08:18:03 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cab653e7c7 | |||
| 8d999a8edd | |||
| 7b773ac088 | |||
| fc58ea7487 | |||
| c61cea0eb1 | |||
| 764b25bd07 | |||
| a66cd25787 | |||
| 0e8d94750b | |||
| 3c915189f4 | |||
| c5541cddeb | |||
| 63561609a6 | |||
| 5dc356ddb0 | |||
| dc36fd38d6 | |||
| 26873bf3d5 | |||
| ff53323790 | |||
| fd3869d380 | |||
| 1d538bc59d | |||
| 784cfcd49e |
+1
-1
@@ -32,6 +32,6 @@ after_success: |
|
||||
cp -r serde_macros/target/doc target/doc/serde_macros &&
|
||||
cp -r serde_json/target/doc target/doc/serde_json &&
|
||||
echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2`/index.html>" > target/doc/index.html &&
|
||||
sudo pip install ghp-import &&
|
||||
pip install ghp-import &&
|
||||
ghp-import -n target/doc &&
|
||||
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
|
||||
|
||||
@@ -10,78 +10,210 @@ information. In many situations, the handshake protocol between serializers and
|
||||
serializees can be completely optimized away, leaving Serde to perform roughly
|
||||
the same speed as a hand written serializer for a specific type.
|
||||
|
||||
Documentation is available at http://serde-rs.github.io/serde/serde
|
||||
Documentation is available at:
|
||||
|
||||
Making a Type Serializable
|
||||
==========================
|
||||
* [serde](https://serde-rs.github.io/serde/serde/serde/index.html)
|
||||
* [serde\_json](https://serde-rs.github.io/serde/serde_json/serde_json/index.html)
|
||||
* [serde\_codegen](https://serde-rs.github.io/serde/serde_codegen/serde_codegen/index.html)
|
||||
|
||||
The simplest way to make a type serializable is to use the `serde_macros`
|
||||
syntax extension, which comes with a `#[derive(Serialize, Deserialize)]`
|
||||
annotation, which automatically generates implementations of
|
||||
[Serialize](http://serde-rs.github.io/serde/serde/ser/trait.Serialize.html)
|
||||
and
|
||||
[Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
|
||||
for the annotated type:
|
||||
Using Serde
|
||||
===========
|
||||
|
||||
Here is a simple example that demonstrates how to use Serde by serializing and
|
||||
deserializing to JSON. Serde comes with some powerful code generation libraries
|
||||
that work with Stable and Nightly Rust that eliminate much of the complexity of
|
||||
hand rolling serialization and deserialization for a given type. First lets see
|
||||
how we would use Nightly Rust, which is currently a bit simpler than Stable
|
||||
Rust:
|
||||
|
||||
`Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[package]
|
||||
name = "serde_example_nightly"
|
||||
version = "0.1.0"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
serde = "*"
|
||||
serde_json = "*"
|
||||
serde_macros = "*"
|
||||
```
|
||||
|
||||
`src/main.rs`
|
||||
|
||||
```rust
|
||||
#![feature(custom_derive, plugin)]
|
||||
#![plugin(serde_macros)]
|
||||
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
...
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let point = Point { x: 1, y: 2 };
|
||||
let serialized = serde_json::to_string(&point).unwrap();
|
||||
|
||||
println!("{}", serialized);
|
||||
|
||||
let deserialized: Point = serde_json::from_str(&serialized_point).unwrap();
|
||||
|
||||
println!("{:?}", deserialized);
|
||||
}
|
||||
```
|
||||
|
||||
Serde bundles a high performance JSON serializer and deserializer,
|
||||
[serde_json](http://serde-rs.github.io/serde/serde_json/index.html),
|
||||
which comes with the helper functions
|
||||
[to_string](http://serde-rs.github.io/serde/serde/json/ser/fn.to_string.html)
|
||||
and
|
||||
[from_str](http://serde-rs.github.io/serde/serde/json/de/fn.from_str.html)
|
||||
that make it easy to go to and from JSON:
|
||||
When run, it produces:
|
||||
|
||||
```
|
||||
% cargo run
|
||||
{"x":1,"y":2}
|
||||
Point { x: 1, y: 2 }
|
||||
```
|
||||
|
||||
Stable Rust is a little more complicated because it does not yet support
|
||||
compiler plugins. Instead we need to use the code generation library
|
||||
[syntex](https://github.com/erickt/rust-syntex) for this:
|
||||
|
||||
```toml
|
||||
[package]
|
||||
name = "serde_example"
|
||||
version = "0.1.0"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
serde_codegen = "*"
|
||||
syntex = "*"
|
||||
|
||||
[dependencies]
|
||||
serde = "*"
|
||||
serde_json = "*"
|
||||
```
|
||||
|
||||
`src/main.rs`:
|
||||
|
||||
```rust
|
||||
use serde_json;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
...
|
||||
|
||||
let point = Point { x: 1, y: 2 };
|
||||
let serialized_point = json::to_string(&point).unwrap();
|
||||
|
||||
println!("{}", serialized_point); // prints: {"x":1,"y":2}
|
||||
|
||||
let deserialize_point: Point = json::from_str(&serialized_point).unwrap();
|
||||
include!(concat!(env!("OUT_DIR"), "/main.rs"));
|
||||
```
|
||||
|
||||
[serde_json](http://serde-rs.github.io/serde/serde_json/index.html) also
|
||||
supports a generic
|
||||
[Value](http://serde-rs.github.io/serde/serde/json/value/enum.Value.html)
|
||||
type, which can represent any JSON value. Also, any
|
||||
[Serialize](http://serde-rs.github.io/serde/serde/ser/trait.Serialize.html)
|
||||
and
|
||||
[Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
|
||||
can be converted into a
|
||||
[Value](http://serde-rs.github.io/serde/serde/json/value/enum.Value.html)
|
||||
with the methods
|
||||
[to_value](http://serde-rs.github.io/serde/serde/json/value/fn.to_value.html)
|
||||
and
|
||||
[from_value](http://serde-rs.github.io/serde/serde/json/value/fn.from_value.html):
|
||||
`src/main.rs.in`:
|
||||
|
||||
```rust
|
||||
let point = Point { x: 1, y: 2 };
|
||||
let point_value = json::to_value(&point).unwrap();
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
println!("{}", point_value.find("x")); // prints: Some(1)
|
||||
fn main() {
|
||||
let point = Point { x: 1, y: 2 };
|
||||
let serialized = serde_json::to_string(&point).unwrap();
|
||||
|
||||
let deserialize_point: Point = json::from_value(point_value).unwrap();
|
||||
println!("{}", serialized);
|
||||
|
||||
let deserialized: Point = serde_json::from_str(&serialized_point).unwrap();
|
||||
|
||||
println!("{:?}", deserialized);
|
||||
}
|
||||
```
|
||||
|
||||
This also produces:
|
||||
|
||||
```
|
||||
% cargo run
|
||||
{"x":1,"y":2}
|
||||
Point { x: 1, y: 2 }
|
||||
```
|
||||
|
||||
While this works well with Stable Rust, be aware that the error locations
|
||||
currently are reported in the generated file instead of in the source file. You
|
||||
may find it easier to develop with Nightly Rust and `serde\_macros`, then
|
||||
deploy with Stable Rust and `serde_codegen`. It's possible to combine both
|
||||
approaches in one setup:
|
||||
|
||||
`Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[package]
|
||||
name = "serde_example"
|
||||
version = "0.1.0"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
build = "build.rs"
|
||||
|
||||
[features]
|
||||
default = ["serde_codegen"]
|
||||
nightly = ["serde_macros"]
|
||||
|
||||
[build-dependencies]
|
||||
serde_codegen = { version = "*", optional = true }
|
||||
syntex = "*"
|
||||
|
||||
[dependencies]
|
||||
serde = "*"
|
||||
serde_json = "*"
|
||||
serde_macros = { version = "*", optional = true }
|
||||
```
|
||||
|
||||
`build.rs`:
|
||||
|
||||
```rust
|
||||
#[cfg(not(feature = "serde_macros"))]
|
||||
mod inner {
|
||||
extern crate syntex;
|
||||
extern crate serde_codegen;
|
||||
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let src = Path::new("src/main.rs.in");
|
||||
let dst = Path::new(&out_dir).join("main.rs");
|
||||
|
||||
let mut registry = syntex::Registry::new();
|
||||
|
||||
serde_codegen::register(&mut registry);
|
||||
registry.expand("", &src, &dst).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde_macros")]
|
||||
mod inner {
|
||||
pub fn main() {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
inner::main();
|
||||
}
|
||||
```
|
||||
|
||||
`src/main.rs`:
|
||||
|
||||
```rust
|
||||
#![cfg_attr(feature = "serde_macros", feature(custom_derive, plugin))]
|
||||
#![cfg_attr(feature = "serde_macros", plugin(serde_macros))]
|
||||
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
#[cfg(feature = "serde_macros")]
|
||||
include!("main.rs.in");
|
||||
|
||||
#[cfg(not(feature = "serde_macros"))]
|
||||
include!(concat!(env!("OUT_DIR"), "/main.rs"));
|
||||
```
|
||||
|
||||
The `src/main.rs.in` is the same as before.
|
||||
|
||||
Serialization without Macros
|
||||
============================
|
||||
|
||||
@@ -206,11 +338,11 @@ impl<'a> serde::ser::MapVisitor for PointMapVisitor<'a> {
|
||||
match self.state {
|
||||
0 => {
|
||||
self.state += 1;
|
||||
Ok(Some(try!(serializer.visit_map_elt("x", &self.value.x))))
|
||||
Ok(Some(try!(serializer.visit_struct_elt("x", &self.value.x))))
|
||||
}
|
||||
1 => {
|
||||
self.state += 1;
|
||||
Ok(Some(try!(serializer.visit_map_elt("y", &self.value.y))))
|
||||
Ok(Some(try!(serializer.visit_struct_elt("y", &self.value.y))))
|
||||
}
|
||||
_ => {
|
||||
Ok(None)
|
||||
@@ -392,7 +524,9 @@ struct PointVisitor;
|
||||
impl serde::de::Visitor for PointVisitor {
|
||||
type Value = Point;
|
||||
|
||||
fn visit_map<V>(&mut self, mut visitor: V) -> Result<Point, V::Error>
|
||||
fn visit_struct<V>(&mut self,
|
||||
_fields: &[&str],
|
||||
mut visitor: V) -> Result<Point, V::Error>
|
||||
where V: serde::de::MapVisitor
|
||||
{
|
||||
let mut x = None;
|
||||
@@ -422,3 +556,14 @@ impl serde::de::Visitor for PointVisitor {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Serialization Formats Using Serde
|
||||
=================================
|
||||
|
||||
| Format | Name |
|
||||
| ------ | ---- |
|
||||
| Bincode | [bincode](https://crates.io/crates/bincode) |
|
||||
| JSON | [serde\_json](https://crates.io/crates/serde_json) |
|
||||
| MessagePack | [rmp](https://crates.io/crates/rmp) |
|
||||
| XML | [serde\_xml](https://github.com/serde-rs/xml) |
|
||||
| YAML | [serde\_yaml](https://github.com/serde-rs/yaml/) |
|
||||
|
||||
+3
-3
@@ -1,13 +1,13 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "0.5.0"
|
||||
version = "0.5.2"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "http://serde-rs.github.io/serde/serde"
|
||||
documentation = "https://serde-rs.github.io/serde/serde/serde/index.html"
|
||||
readme = "../README.md"
|
||||
keywords = ["serialization"]
|
||||
keywords = ["serde", "serialization"]
|
||||
|
||||
[dependencies]
|
||||
num = "*"
|
||||
|
||||
+21
-80
@@ -10,8 +10,6 @@ use std::collections::{
|
||||
};
|
||||
#[cfg(feature = "nightly")]
|
||||
use collections::enum_set::{CLike, EnumSet};
|
||||
#[cfg(feature = "nightly")]
|
||||
use collections::vec_map::VecMap;
|
||||
use std::hash::Hash;
|
||||
use std::marker::PhantomData;
|
||||
use std::path;
|
||||
@@ -34,6 +32,7 @@ use de::{
|
||||
Error,
|
||||
MapVisitor,
|
||||
SeqVisitor,
|
||||
Type,
|
||||
VariantVisitor,
|
||||
Visitor,
|
||||
};
|
||||
@@ -85,7 +84,7 @@ impl Visitor for BoolVisitor {
|
||||
match s.trim() {
|
||||
"true" => Ok(true),
|
||||
"false" => Ok(false),
|
||||
_ => Err(Error::syntax("expected `true` or `false`")),
|
||||
_ => Err(Error::type_mismatch(Type::Bool)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,14 +100,14 @@ impl Deserialize for bool {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
macro_rules! impl_deserialize_num_method {
|
||||
($src_ty:ty, $method:ident, $from_method:ident) => {
|
||||
($src_ty:ty, $method:ident, $from_method:ident, $ty:expr) => {
|
||||
#[inline]
|
||||
fn $method<E>(&mut self, v: $src_ty) -> Result<T, E>
|
||||
where E: Error,
|
||||
{
|
||||
match FromPrimitive::$from_method(v) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(Error::syntax("expected a number")),
|
||||
None => Err(Error::type_mismatch($ty)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,24 +131,24 @@ impl<
|
||||
> Visitor for PrimitiveVisitor<T> {
|
||||
type Value = T;
|
||||
|
||||
impl_deserialize_num_method!(isize, visit_isize, from_isize);
|
||||
impl_deserialize_num_method!(i8, visit_i8, from_i8);
|
||||
impl_deserialize_num_method!(i16, visit_i16, from_i16);
|
||||
impl_deserialize_num_method!(i32, visit_i32, from_i32);
|
||||
impl_deserialize_num_method!(i64, visit_i64, from_i64);
|
||||
impl_deserialize_num_method!(usize, visit_usize, from_usize);
|
||||
impl_deserialize_num_method!(u8, visit_u8, from_u8);
|
||||
impl_deserialize_num_method!(u16, visit_u16, from_u16);
|
||||
impl_deserialize_num_method!(u32, visit_u32, from_u32);
|
||||
impl_deserialize_num_method!(u64, visit_u64, from_u64);
|
||||
impl_deserialize_num_method!(f32, visit_f32, from_f32);
|
||||
impl_deserialize_num_method!(f64, visit_f64, from_f64);
|
||||
impl_deserialize_num_method!(isize, visit_isize, from_isize, Type::Isize);
|
||||
impl_deserialize_num_method!(i8, visit_i8, from_i8, Type::I8);
|
||||
impl_deserialize_num_method!(i16, visit_i16, from_i16, Type::I16);
|
||||
impl_deserialize_num_method!(i32, visit_i32, from_i32, Type::I32);
|
||||
impl_deserialize_num_method!(i64, visit_i64, from_i64, Type::I64);
|
||||
impl_deserialize_num_method!(usize, visit_usize, from_usize, Type::Usize);
|
||||
impl_deserialize_num_method!(u8, visit_u8, from_u8, Type::U8);
|
||||
impl_deserialize_num_method!(u16, visit_u16, from_u16, Type::U16);
|
||||
impl_deserialize_num_method!(u32, visit_u32, from_u32, Type::U32);
|
||||
impl_deserialize_num_method!(u64, visit_u64, from_u64, Type::U64);
|
||||
impl_deserialize_num_method!(f32, visit_f32, from_f32, Type::F32);
|
||||
impl_deserialize_num_method!(f64, visit_f64, from_f64, Type::F64);
|
||||
|
||||
#[inline]
|
||||
fn visit_str<E>(&mut self, v: &str) -> Result<T, E>
|
||||
where E: Error,
|
||||
{
|
||||
str::FromStr::from_str(v.trim()).or(Err(Error::syntax("expected a str")))
|
||||
str::FromStr::from_str(v.trim()).or(Err(Error::type_mismatch(Type::Str)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +199,7 @@ impl Visitor for CharVisitor {
|
||||
let mut iter = v.chars();
|
||||
if let Some(v) = iter.next() {
|
||||
if iter.next().is_some() {
|
||||
Err(Error::syntax("expected a character"))
|
||||
Err(Error::type_mismatch(Type::Char))
|
||||
} else {
|
||||
Ok(v)
|
||||
}
|
||||
@@ -243,7 +242,7 @@ impl Visitor for StringVisitor {
|
||||
{
|
||||
match str::from_utf8(v) {
|
||||
Ok(s) => Ok(s.to_string()),
|
||||
Err(_) => Err(Error::syntax("expected utf8 `&[u8]`")),
|
||||
Err(_) => Err(Error::type_mismatch(Type::String)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +251,7 @@ impl Visitor for StringVisitor {
|
||||
{
|
||||
match String::from_utf8(v) {
|
||||
Ok(s) => Ok(s),
|
||||
Err(_) => Err(Error::syntax("expected utf8 `&[u8]`")),
|
||||
Err(_) => Err(Error::type_mismatch(Type::String)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -718,64 +717,6 @@ map_impl!(
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
pub struct VecMapVisitor<V> {
|
||||
marker: PhantomData<VecMap<V>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<V> VecMapVisitor<V> {
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
VecMapVisitor {
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<V> Visitor for VecMapVisitor<V>
|
||||
where V: Deserialize,
|
||||
{
|
||||
type Value = VecMap<V>;
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<VecMap<V>, E>
|
||||
where E: Error,
|
||||
{
|
||||
Ok(VecMap::new())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<VecMap<V>, V_::Error>
|
||||
where V_: MapVisitor,
|
||||
{
|
||||
let (len, _) = visitor.size_hint();
|
||||
let mut values = VecMap::with_capacity(len);
|
||||
|
||||
while let Some((key, value)) = try!(visitor.visit()) {
|
||||
values.insert(key, value);
|
||||
}
|
||||
|
||||
try!(visitor.end());
|
||||
|
||||
Ok(values)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<V> Deserialize for VecMap<V>
|
||||
where V: Deserialize,
|
||||
{
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<VecMap<V>, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
deserializer.visit_map(VecMapVisitor::new())
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PathBufVisitor;
|
||||
|
||||
impl Visitor for PathBufVisitor {
|
||||
@@ -900,7 +841,7 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
|
||||
_ => {
|
||||
match str::from_utf8(value) {
|
||||
Ok(value) => Err(Error::unknown_field(value)),
|
||||
Err(_) => Err(Error::syntax("expected a `&[u8]`")),
|
||||
Err(_) => Err(Error::type_mismatch(Type::String)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+76
-25
@@ -5,16 +5,67 @@ pub mod value;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub trait Error {
|
||||
/// `Error` is a trait that allows a `Deserialize` to generically create a
|
||||
/// `Deserializer` error.
|
||||
pub trait Error: Sized {
|
||||
/// Raised when there is general error when deserializing a type.
|
||||
fn syntax(msg: &str) -> Self;
|
||||
|
||||
/// Raised when a fixed sized sequence or map was passed in the wrong amount of arguments.
|
||||
fn length_mismatch(_len: usize) -> Self {
|
||||
Error::syntax("incorrect length")
|
||||
}
|
||||
|
||||
/// Raised when a `Deserialize` was passed an incorrect type.
|
||||
fn type_mismatch(_type: Type) -> Self {
|
||||
Error::syntax("incorrect type")
|
||||
}
|
||||
|
||||
/// Raised when a `Deserialize` type unexpectedly hit the end of the stream.
|
||||
fn end_of_stream() -> Self;
|
||||
|
||||
/// Raised when a `Deserialize` struct type received an unexpected struct field.
|
||||
fn unknown_field(field: &str) -> Self;
|
||||
|
||||
/// Raised when a `Deserialize` struct type did not receive a field.
|
||||
fn missing_field(field: &'static str) -> Self;
|
||||
}
|
||||
|
||||
/// `Type` represents all the primitive types that can be deserialized. This is used by
|
||||
/// `Error::kind_mismatch`.
|
||||
pub enum Type {
|
||||
Bool,
|
||||
Usize,
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
Isize,
|
||||
I8,
|
||||
I16,
|
||||
I32,
|
||||
I64,
|
||||
F32,
|
||||
F64,
|
||||
Char,
|
||||
Str,
|
||||
String,
|
||||
Unit,
|
||||
Option,
|
||||
Seq,
|
||||
Map,
|
||||
UnitStruct,
|
||||
NewtypeStruct,
|
||||
TupleStruct,
|
||||
Struct,
|
||||
Tuple,
|
||||
Enum,
|
||||
StructVariant,
|
||||
TupleVariant,
|
||||
UnitVariant,
|
||||
Bytes,
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub trait Deserialize {
|
||||
@@ -57,7 +108,7 @@ pub trait Deserializer {
|
||||
fn visit_usize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
self.visit_u64(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `u8` value.
|
||||
@@ -65,7 +116,7 @@ pub trait Deserializer {
|
||||
fn visit_u8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
self.visit_u64(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `u16` value.
|
||||
@@ -73,7 +124,7 @@ pub trait Deserializer {
|
||||
fn visit_u16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
self.visit_u64(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `u32` value.
|
||||
@@ -81,7 +132,7 @@ pub trait Deserializer {
|
||||
fn visit_u32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
self.visit_u64(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `u64` value.
|
||||
@@ -97,7 +148,7 @@ pub trait Deserializer {
|
||||
fn visit_isize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
self.visit_i64(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `i8` value.
|
||||
@@ -105,7 +156,7 @@ pub trait Deserializer {
|
||||
fn visit_i8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
self.visit_i64(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `i16` value.
|
||||
@@ -113,7 +164,7 @@ pub trait Deserializer {
|
||||
fn visit_i16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
self.visit_i64(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `i32` value.
|
||||
@@ -121,7 +172,7 @@ pub trait Deserializer {
|
||||
fn visit_i32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
self.visit_i64(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting an `i64` value.
|
||||
@@ -137,7 +188,7 @@ pub trait Deserializer {
|
||||
fn visit_f32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
self.visit_f64(visitor)
|
||||
}
|
||||
|
||||
/// This method hints that the `Deserialize` type is expecting a `f64` value.
|
||||
@@ -304,7 +355,7 @@ pub trait Visitor {
|
||||
fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::syntax("expected a bool"))
|
||||
Err(Error::type_mismatch(Type::Bool))
|
||||
}
|
||||
|
||||
fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E>
|
||||
@@ -334,7 +385,7 @@ pub trait Visitor {
|
||||
fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::syntax("expected a i64"))
|
||||
Err(Error::type_mismatch(Type::I64))
|
||||
}
|
||||
|
||||
fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E>
|
||||
@@ -364,7 +415,7 @@ pub trait Visitor {
|
||||
fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::syntax("expected a u64"))
|
||||
Err(Error::type_mismatch(Type::U64))
|
||||
}
|
||||
|
||||
fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E>
|
||||
@@ -376,7 +427,7 @@ pub trait Visitor {
|
||||
fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::syntax("expected a f64"))
|
||||
Err(Error::type_mismatch(Type::F64))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -391,7 +442,7 @@ pub trait Visitor {
|
||||
fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::syntax("expected a str"))
|
||||
Err(Error::type_mismatch(Type::Str))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -404,7 +455,7 @@ pub trait Visitor {
|
||||
fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::syntax("expected a unit"))
|
||||
Err(Error::type_mismatch(Type::Unit))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -417,37 +468,37 @@ pub trait Visitor {
|
||||
fn visit_none<E>(&mut self) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::syntax("expected an Option::None"))
|
||||
Err(Error::type_mismatch(Type::Option))
|
||||
}
|
||||
|
||||
fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
Err(Error::syntax("expected an Option::Some"))
|
||||
Err(Error::type_mismatch(Type::Option))
|
||||
}
|
||||
|
||||
fn visit_newtype_struct<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
|
||||
where D: Deserializer,
|
||||
{
|
||||
Err(Error::syntax("expected a newtype struct"))
|
||||
Err(Error::type_mismatch(Type::NewtypeStruct))
|
||||
}
|
||||
|
||||
fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
|
||||
where V: SeqVisitor,
|
||||
{
|
||||
Err(Error::syntax("expected a sequence"))
|
||||
Err(Error::type_mismatch(Type::Seq))
|
||||
}
|
||||
|
||||
fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
|
||||
where V: MapVisitor,
|
||||
{
|
||||
Err(Error::syntax("expected a map"))
|
||||
Err(Error::type_mismatch(Type::Map))
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(&mut self, _v: &[u8]) -> Result<Self::Value, E>
|
||||
where E: Error,
|
||||
{
|
||||
Err(Error::syntax("expected a &[u8]"))
|
||||
Err(Error::type_mismatch(Type::Bytes))
|
||||
}
|
||||
|
||||
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||
@@ -593,7 +644,7 @@ pub trait VariantVisitor {
|
||||
|
||||
/// `visit_unit` is called when deserializing a variant with no values.
|
||||
fn visit_unit(&mut self) -> Result<(), Self::Error> {
|
||||
Err(Error::syntax("expected a univ variant"))
|
||||
Err(Error::type_mismatch(Type::UnitVariant))
|
||||
}
|
||||
|
||||
/// `visit_newtype` is called when deserializing a variant with a single value. By default this
|
||||
@@ -612,7 +663,7 @@ pub trait VariantVisitor {
|
||||
_visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor
|
||||
{
|
||||
Err(Error::syntax("expected a tuple variant"))
|
||||
Err(Error::type_mismatch(Type::TupleVariant))
|
||||
}
|
||||
|
||||
/// `visit_struct` is called when deserializing a struct-like variant.
|
||||
@@ -621,7 +672,7 @@ pub trait VariantVisitor {
|
||||
_visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor
|
||||
{
|
||||
Err(Error::syntax("expected a struct variant"))
|
||||
Err(Error::type_mismatch(Type::StructVariant))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ impl<I, T> de::SeqVisitor for SeqDeserializer<I>
|
||||
if self.len == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(de::Error::end_of_stream())
|
||||
Err(de::Error::length_mismatch(self.len))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,7 +382,7 @@ impl<I, K, V> de::MapVisitor for MapDeserializer<I, K, V>
|
||||
if self.len == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(de::Error::end_of_stream())
|
||||
Err(de::Error::length_mismatch(self.len))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//! leaving serde to perform roughly the same speed as a hand written serializer for a specific
|
||||
//! type.
|
||||
#![doc(html_root_url="https://serde-rs.github.io/serde/serde")]
|
||||
#![cfg_attr(feature = "nightly", feature(collections, core, enumset, nonzero, step_trait, vecmap, zero_one))]
|
||||
#![cfg_attr(feature = "nightly", feature(collections, core, enumset, nonzero, step_trait, zero_one))]
|
||||
|
||||
extern crate num;
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ use std::collections::{
|
||||
};
|
||||
#[cfg(feature = "nightly")]
|
||||
use collections::enum_set::{CLike, EnumSet};
|
||||
#[cfg(feature = "nightly")]
|
||||
use std::collections::vec_map::VecMap;
|
||||
use std::hash::Hash;
|
||||
#[cfg(feature = "nightly")]
|
||||
use std::iter;
|
||||
@@ -558,18 +556,6 @@ impl<K, V> Serialize for HashMap<K, V>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<V> Serialize for VecMap<V>
|
||||
where V: Serialize,
|
||||
{
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: Serializer,
|
||||
{
|
||||
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl<'a, T: ?Sized> Serialize for &'a T where T: Serialize {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
[package]
|
||||
name = "serde_codegen"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros to auto-generate implementations for the serde framework"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "https://serde-rs.github.io/serde/serde_codegen/serde_codegen/index.html"
|
||||
build = "build.rs"
|
||||
keywords = ["serde", "serialization"]
|
||||
|
||||
[features]
|
||||
default = ["with-syntex"]
|
||||
|
||||
@@ -320,7 +320,7 @@ fn deserialize_newtype_struct(
|
||||
type Value = $ty;
|
||||
|
||||
#[inline]
|
||||
fn visit_newtype_struct<D>(&mut self, deserializer: &mut D) -> Result<Self::Value, D::Error>
|
||||
fn visit_newtype_struct<D>(&mut self, deserializer: &mut D) -> ::std::result::Result<Self::Value, D::Error>
|
||||
where D: ::serde::de::Deserializer,
|
||||
{
|
||||
let value = try!(::serde::de::Deserialize::deserialize(deserializer));
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
[package]
|
||||
name = "serde_json"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A JSON serialization file format"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "http://serde-rs.github.io/serde/serde"
|
||||
documentation = "https://serde-rs.github.io/serde/serde_json/serde_json/index.html"
|
||||
readme = "../README.md"
|
||||
keywords = ["serialization", "json"]
|
||||
keywords = ["json", "serde", "serialization"]
|
||||
|
||||
[dependencies]
|
||||
num = "*"
|
||||
|
||||
@@ -54,8 +54,14 @@ impl<Iter> Deserializer<Iter>
|
||||
match self.ch {
|
||||
Some(ch) => Ok(Some(ch)),
|
||||
None => {
|
||||
self.ch = try!(self.next_char());
|
||||
Ok(self.ch)
|
||||
match self.rdr.next() {
|
||||
Some(Err(err)) => Err(Error::IoError(err)),
|
||||
Some(Ok(ch)) => {
|
||||
self.ch = Some(ch);
|
||||
Ok(self.ch)
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,13 @@
|
||||
extern crate num;
|
||||
extern crate serde;
|
||||
|
||||
pub use self::de::{Deserializer, from_str};
|
||||
pub use self::de::{
|
||||
Deserializer,
|
||||
from_iter,
|
||||
from_reader,
|
||||
from_slice,
|
||||
from_str,
|
||||
};
|
||||
pub use self::error::{Error, ErrorCode, Result};
|
||||
pub use self::ser::{
|
||||
Serializer,
|
||||
|
||||
@@ -843,7 +843,7 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
|
||||
if self.len == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(de::Error::end_of_stream())
|
||||
Err(de::Error::length_mismatch(self.len))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,7 +888,7 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> {
|
||||
if self.len == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(de::Error::end_of_stream())
|
||||
Err(de::Error::length_mismatch(self.len))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
[package]
|
||||
name = "serde_macros"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros to auto-generate implementations for the serde framework"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "https://github.com/serde-rs/serde"
|
||||
keywords = ["serde", "serialization"]
|
||||
|
||||
[lib]
|
||||
name = "serde_macros"
|
||||
|
||||
Reference in New Issue
Block a user