mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-24 06:27:59 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eb9c860cb4 | |||
| cf38b8dae5 | |||
| 75af81234f | |||
| 7cc319acca | |||
| 3b44792ff3 | |||
| 678bad241e | |||
| 5b1225cc87 | |||
| 1748831152 | |||
| ed1b476a22 | |||
| 79c59ebae1 | |||
| fd6462f8d1 | |||
| c37f67b0a1 | |||
| 195f7380b5 | |||
| becb8c48e8 | |||
| aa16ecf4d3 | |||
| ddda360fec | |||
| cca72f2dbc | |||
| 5013b37c09 |
+3
-2
@@ -1,10 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A serialization/deserialization framework"
|
description = "A serialization/deserialization framework"
|
||||||
repository = "https://github.com/erickt/rust-serde"
|
repository = "https://github.com/erickt/rust-serde"
|
||||||
|
documentation = "http://erickt.github.io/rust-serde/serde"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num = "*"
|
num = "*"
|
||||||
@@ -14,4 +15,4 @@ rustc-serialize = "*"
|
|||||||
|
|
||||||
[dev-dependencies.serde_macros]
|
[dev-dependencies.serde_macros]
|
||||||
path = "serde_macros/"
|
path = "serde_macros/"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
|
|||||||
@@ -198,18 +198,18 @@ struct PointMapVisitor<'a> {
|
|||||||
state: u8,
|
state: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::ser::MapVisitor for PointMapVisitor {
|
impl<'a> serde::ser::MapVisitor for PointMapVisitor<'a> {
|
||||||
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option(), S::Error>
|
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
|
||||||
where S: serde::Serializer
|
where S: serde::Serializer
|
||||||
{
|
{
|
||||||
match self.state {
|
match self.state {
|
||||||
0 => {
|
0 => {
|
||||||
self.state += 1;
|
self.state += 1;
|
||||||
Ok(Some(try!(serializer.visit_map_elt("x", &self.x)))
|
Ok(Some(try!(serializer.visit_map_elt("x", &self.value.x))))
|
||||||
}
|
}
|
||||||
1 => {
|
1 => {
|
||||||
self.state += 1;
|
self.state += 1;
|
||||||
Ok(Some(try!(serializer.visit_map_elt("y", &self.y))))
|
Ok(Some(try!(serializer.visit_map_elt("y", &self.value.y))))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
@@ -233,7 +233,7 @@ can create the `i32` from a variety of different types:
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
impl Deserialize for i32 {
|
impl Deserialize for i32 {
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
|
fn deserialize<D>(deserializer: &mut D) -> Result<i32, D::Error>
|
||||||
where D: serde::Deserializer,
|
where D: serde::Deserializer,
|
||||||
{
|
{
|
||||||
deserializer.visit(I32Visitor)
|
deserializer.visit(I32Visitor)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_macros"
|
name = "serde_macros"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros to auto-generate implementations for the serde framework"
|
description = "Macros to auto-generate implementations for the serde framework"
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ fn deserialize_struct_visitor(
|
|||||||
let field_visitor = deserialize_field_visitor(
|
let field_visitor = deserialize_field_visitor(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
field::struct_field_strs(cx, builder, struct_def),
|
field::struct_field_strs(cx, builder, struct_def, field::Direction::Deserialize),
|
||||||
);
|
);
|
||||||
|
|
||||||
let visit_map_expr = deserialize_map(
|
let visit_map_expr = deserialize_map(
|
||||||
@@ -639,9 +639,11 @@ fn deserialize_map(
|
|||||||
let extract_values: Vec<P<ast::Stmt>> = field_names.iter()
|
let extract_values: Vec<P<ast::Stmt>> = field_names.iter()
|
||||||
.zip(struct_def.fields.iter())
|
.zip(struct_def.fields.iter())
|
||||||
.map(|(field_name, field)| {
|
.map(|(field_name, field)| {
|
||||||
let name_str = match field.node.kind {
|
let rename = field::field_rename(field, &field::Direction::Deserialize);
|
||||||
ast::NamedField(name, _) => builder.expr().str(name),
|
let name_str = match (rename, field.node.kind) {
|
||||||
ast::UnnamedField(_) => panic!("struct contains unnamed fields"),
|
(Some(rename), _) => builder.expr().build_lit(P(rename.clone())),
|
||||||
|
(None, ast::NamedField(name, _)) => builder.expr().str(name),
|
||||||
|
(None, ast::UnnamedField(_)) => panic!("struct contains unnamed fields"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let missing_expr = if field::default_value(field) {
|
let missing_expr = if field::default_value(field) {
|
||||||
|
|||||||
@@ -5,7 +5,19 @@ use syntax::ptr::P;
|
|||||||
|
|
||||||
use aster;
|
use aster;
|
||||||
|
|
||||||
fn field_rename(field: &ast::StructField) -> Option<&ast::Lit> {
|
pub enum Direction {
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn field_rename<'a>(
|
||||||
|
field: &'a ast::StructField,
|
||||||
|
direction: &Direction,
|
||||||
|
) -> Option<&'a ast::Lit> {
|
||||||
|
let dir_attr = match *direction {
|
||||||
|
Direction::Serialize => "rename_serialize",
|
||||||
|
Direction::Deserialize => "rename_deserialize",
|
||||||
|
};
|
||||||
field.node.attrs.iter()
|
field.node.attrs.iter()
|
||||||
.find(|sa| {
|
.find(|sa| {
|
||||||
if let ast::MetaList(ref n, _) = sa.node.value.node {
|
if let ast::MetaList(ref n, _) = sa.node.value.node {
|
||||||
@@ -19,7 +31,7 @@ fn field_rename(field: &ast::StructField) -> Option<&ast::Lit> {
|
|||||||
attr::mark_used(&sa);
|
attr::mark_used(&sa);
|
||||||
vals.iter().fold(None, |v, mi| {
|
vals.iter().fold(None, |v, mi| {
|
||||||
if let ast::MetaNameValue(ref n, ref lit) = mi.node {
|
if let ast::MetaNameValue(ref n, ref lit) = mi.node {
|
||||||
if n == &"rename" {
|
if n == &"rename" || n == &dir_attr {
|
||||||
Some(lit)
|
Some(lit)
|
||||||
} else {
|
} else {
|
||||||
v
|
v
|
||||||
@@ -38,10 +50,11 @@ pub fn struct_field_strs(
|
|||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
struct_def: &ast::StructDef,
|
struct_def: &ast::StructDef,
|
||||||
|
direction: Direction,
|
||||||
) -> Vec<P<ast::Expr>> {
|
) -> Vec<P<ast::Expr>> {
|
||||||
struct_def.fields.iter()
|
struct_def.fields.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
match field_rename(field) {
|
match field_rename(field, &direction) {
|
||||||
Some(rename) => builder.expr().build_lit(P(rename.clone())),
|
Some(rename) => builder.expr().build_lit(P(rename.clone())),
|
||||||
None => {
|
None => {
|
||||||
match field.node.kind {
|
match field.node.kind {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use syntax::ptr::P;
|
|||||||
|
|
||||||
use aster;
|
use aster;
|
||||||
|
|
||||||
use field::struct_field_strs;
|
use field::{Direction, struct_field_strs};
|
||||||
|
|
||||||
pub fn expand_derive_serialize(
|
pub fn expand_derive_serialize(
|
||||||
cx: &mut ExtCtxt,
|
cx: &mut ExtCtxt,
|
||||||
@@ -517,7 +517,7 @@ fn serialize_struct_visitor<I>(
|
|||||||
{
|
{
|
||||||
let len = struct_def.fields.len();
|
let len = struct_def.fields.len();
|
||||||
|
|
||||||
let key_exprs = struct_field_strs(cx, builder, struct_def);
|
let key_exprs = struct_field_strs(cx, builder, struct_def, Direction::Serialize);
|
||||||
|
|
||||||
let arms: Vec<ast::Arm> = key_exprs.iter()
|
let arms: Vec<ast::Arm> = key_exprs.iter()
|
||||||
.zip(value_exprs)
|
.zip(value_exprs)
|
||||||
|
|||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
use std::io;
|
||||||
|
|
||||||
|
pub struct LineColIterator<Iter: Iterator<Item=io::Result<u8>>> {
|
||||||
|
iter: Iter,
|
||||||
|
line: usize,
|
||||||
|
col: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Iter: Iterator<Item=io::Result<u8>>> LineColIterator<Iter> {
|
||||||
|
pub fn new(iter: Iter) -> LineColIterator<Iter> {
|
||||||
|
LineColIterator {
|
||||||
|
iter: iter,
|
||||||
|
line: 1,
|
||||||
|
col: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Report the current line inside the iterator.
|
||||||
|
pub fn line(&self) -> usize { self.line }
|
||||||
|
|
||||||
|
/// Report the current column inside the iterator.
|
||||||
|
pub fn col(&self) -> usize { self.col }
|
||||||
|
|
||||||
|
/// Gets a reference to the underlying iterator.
|
||||||
|
pub fn get_ref(&self) -> &Iter { &self.iter }
|
||||||
|
|
||||||
|
/// Gets a mutable reference to the underlying iterator.
|
||||||
|
pub fn get_mut(&self) -> &Iter { &self.iter }
|
||||||
|
|
||||||
|
/// Unwraps this `LineColIterator`, returning the underlying iterator.
|
||||||
|
pub fn into_inner(self) -> Iter { self.iter }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Iter: Iterator<Item=io::Result<u8>>> Iterator for LineColIterator<Iter> {
|
||||||
|
type Item = io::Result<u8>;
|
||||||
|
fn next(&mut self) -> Option<io::Result<u8>> {
|
||||||
|
match self.iter.next() {
|
||||||
|
None => None,
|
||||||
|
Some(Ok(b'\n')) => {
|
||||||
|
self.line += 1;
|
||||||
|
self.col = 0;
|
||||||
|
Some(Ok(b'\n'))
|
||||||
|
},
|
||||||
|
Some(Ok(c)) => {
|
||||||
|
self.col += 1;
|
||||||
|
Some(Ok(c))
|
||||||
|
},
|
||||||
|
Some(Err(e)) => Some(Err(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-19
@@ -3,13 +3,13 @@ use std::io;
|
|||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use de;
|
use de;
|
||||||
|
use iter::LineColIterator;
|
||||||
|
|
||||||
use super::error::{Error, ErrorCode};
|
use super::error::{Error, ErrorCode};
|
||||||
|
|
||||||
pub struct Deserializer<Iter> {
|
pub struct Deserializer<Iter: Iterator<Item=io::Result<u8>>> {
|
||||||
rdr: Iter,
|
rdr: LineColIterator<Iter>,
|
||||||
ch: Option<u8>,
|
ch: Option<u8>,
|
||||||
line: usize,
|
|
||||||
col: usize,
|
|
||||||
str_buf: Vec<u8>,
|
str_buf: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,10 +20,8 @@ impl<Iter> Deserializer<Iter>
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(rdr: Iter) -> Result<Deserializer<Iter>, Error> {
|
pub fn new(rdr: Iter) -> Result<Deserializer<Iter>, Error> {
|
||||||
let mut deserializer = Deserializer {
|
let mut deserializer = Deserializer {
|
||||||
rdr: rdr,
|
rdr: LineColIterator::new(rdr),
|
||||||
ch: None,
|
ch: None,
|
||||||
line: 1,
|
|
||||||
col: 0,
|
|
||||||
str_buf: Vec::with_capacity(128),
|
str_buf: Vec::with_capacity(128),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,13 +51,6 @@ impl<Iter> Deserializer<Iter>
|
|||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.ch_is(b'\n') {
|
|
||||||
self.line += 1;
|
|
||||||
self.col = 1;
|
|
||||||
} else {
|
|
||||||
self.col += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +64,7 @@ impl<Iter> Deserializer<Iter>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn error(&mut self, reason: ErrorCode) -> Error {
|
fn error(&mut self, reason: ErrorCode) -> Error {
|
||||||
Error::SyntaxError(reason, self.line, self.col)
|
Error::SyntaxError(reason, self.rdr.line(), self.rdr.col())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_whitespace(&mut self) -> Result<(), Error> {
|
fn parse_whitespace(&mut self) -> Result<(), Error> {
|
||||||
@@ -476,12 +467,12 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SeqVisitor<'a, Iter: 'a> {
|
struct SeqVisitor<'a, Iter: 'a + Iterator<Item=io::Result<u8>>> {
|
||||||
de: &'a mut Deserializer<Iter>,
|
de: &'a mut Deserializer<Iter>,
|
||||||
first: bool,
|
first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Iter> SeqVisitor<'a, Iter> {
|
impl<'a, Iter: Iterator<Item=io::Result<u8>>> SeqVisitor<'a, Iter> {
|
||||||
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||||
SeqVisitor {
|
SeqVisitor {
|
||||||
de: de,
|
de: de,
|
||||||
@@ -533,12 +524,12 @@ impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MapVisitor<'a, Iter: 'a> {
|
struct MapVisitor<'a, Iter: 'a + Iterator<Item=io::Result<u8>>> {
|
||||||
de: &'a mut Deserializer<Iter>,
|
de: &'a mut Deserializer<Iter>,
|
||||||
first: bool,
|
first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Iter> MapVisitor<'a, Iter> {
|
impl<'a, Iter: Iterator<Item=io::Result<u8>>> MapVisitor<'a, Iter> {
|
||||||
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||||
MapVisitor {
|
MapVisitor {
|
||||||
de: de,
|
de: de,
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::num::{Float, FpCategory};
|
use std::num::FpCategory;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
|
|
||||||
use ser;
|
use ser;
|
||||||
|
|||||||
+5
-3
@@ -5,13 +5,15 @@
|
|||||||
//! handshake protocol between serializers and serializees can be completely optimized away,
|
//! 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
|
//! leaving serde to perform roughly the same speed as a hand written serializer for a specific
|
||||||
//! type.
|
//! type.
|
||||||
|
#![doc(html_root_url="http://erickt.github.io/rust-serde")]
|
||||||
|
|
||||||
extern crate num;
|
extern crate num;
|
||||||
|
|
||||||
pub use ser::{Serialize, Serializer};
|
pub use ser::{Serialize, Serializer};
|
||||||
pub use de::{Deserialize, Deserializer, Error};
|
pub use de::{Deserialize, Deserializer, Error};
|
||||||
|
|
||||||
pub mod ser;
|
|
||||||
pub mod de;
|
|
||||||
pub mod json;
|
|
||||||
pub mod bytes;
|
pub mod bytes;
|
||||||
|
pub mod de;
|
||||||
|
pub mod iter;
|
||||||
|
pub mod json;
|
||||||
|
pub mod ser;
|
||||||
|
|||||||
@@ -20,6 +20,13 @@ struct Rename {
|
|||||||
a2: i32,
|
a2: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
struct DirectionRename {
|
||||||
|
a1: i32,
|
||||||
|
#[serde(rename_serialize="a3", rename_deserialize="a4")]
|
||||||
|
a2: i32,
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_default() {
|
fn test_default() {
|
||||||
let deserialized_value: Default = json::from_str(&"{\"a1\":1,\"a2\":2}").unwrap();
|
let deserialized_value: Default = json::from_str(&"{\"a1\":1,\"a2\":2}").unwrap();
|
||||||
@@ -38,3 +45,13 @@ fn test_rename() {
|
|||||||
let deserialized_value: Rename = json::from_str(&serialized_value).unwrap();
|
let deserialized_value: Rename = json::from_str(&serialized_value).unwrap();
|
||||||
assert_eq!(value, deserialized_value);
|
assert_eq!(value, deserialized_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_direction_rename() {
|
||||||
|
let value = DirectionRename { a1: 1, a2: 2 };
|
||||||
|
let serialized_value = json::to_string(&value).unwrap();
|
||||||
|
assert_eq!(serialized_value, "{\"a1\":1,\"a3\":2}");
|
||||||
|
|
||||||
|
let deserialized_value = json::from_str("{\"a1\":1,\"a4\":2}").unwrap();
|
||||||
|
assert_eq!(value, deserialized_value);
|
||||||
|
}
|
||||||
|
|||||||
+50
-27
@@ -1,4 +1,4 @@
|
|||||||
#![feature(custom_derive, plugin, test)]
|
#![feature(custom_derive, plugin, test, custom_attribute)]
|
||||||
#![plugin(serde_macros)]
|
#![plugin(serde_macros)]
|
||||||
|
|
||||||
extern crate test;
|
extern crate test;
|
||||||
@@ -668,8 +668,8 @@ fn test_parse_err<T>(errors: Vec<(&'static str, Error)>)
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_null() {
|
fn test_parse_null() {
|
||||||
test_parse_err::<()>(vec![
|
test_parse_err::<()>(vec![
|
||||||
("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
|
("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)),
|
||||||
("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
|
("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
|
||||||
("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
|
("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -681,9 +681,9 @@ fn test_parse_null() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_bool() {
|
fn test_parse_bool() {
|
||||||
test_parse_err::<bool>(vec![
|
test_parse_err::<bool>(vec![
|
||||||
("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
|
("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)),
|
||||||
("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
|
("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
|
||||||
("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
|
("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)),
|
||||||
("faz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
|
("faz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
|
||||||
("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
|
("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
|
||||||
("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
|
("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
|
||||||
@@ -702,11 +702,11 @@ fn test_parse_number_errors() {
|
|||||||
test_parse_err::<f64>(vec![
|
test_parse_err::<f64>(vec![
|
||||||
("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
|
("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
|
||||||
(".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
|
(".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
|
||||||
("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
|
("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 1)),
|
||||||
("00", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
|
("00", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
|
||||||
("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
|
("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
|
||||||
("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
|
("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
|
||||||
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 4)),
|
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
|
||||||
("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
|
("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -745,8 +745,8 @@ fn test_parse_f64() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_string() {
|
fn test_parse_string() {
|
||||||
test_parse_err::<String>(vec![
|
test_parse_err::<String>(vec![
|
||||||
("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)),
|
("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 1)),
|
||||||
("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)),
|
("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 4)),
|
||||||
("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
|
("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -767,10 +767,10 @@ fn test_parse_string() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_list() {
|
fn test_parse_list() {
|
||||||
test_parse_err::<Vec<f64>>(vec![
|
test_parse_err::<Vec<f64>>(vec![
|
||||||
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
|
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)),
|
||||||
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
|
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
|
||||||
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 3)),
|
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 2)),
|
||||||
("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 4)),
|
("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
|
||||||
("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)),
|
("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)),
|
||||||
("[1 2]", Error::SyntaxError(ErrorCode::ExpectedListCommaOrEnd, 1, 4)),
|
("[1 2]", Error::SyntaxError(ErrorCode::ExpectedListCommaOrEnd, 1, 4)),
|
||||||
("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
|
("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
|
||||||
@@ -819,17 +819,17 @@ fn test_parse_list() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_object() {
|
fn test_parse_object() {
|
||||||
test_parse_err::<BTreeMap<String, u32>>(vec![
|
test_parse_err::<BTreeMap<String, u32>>(vec![
|
||||||
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
|
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)),
|
||||||
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
|
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
|
||||||
("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)),
|
("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)),
|
||||||
("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
|
("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
|
||||||
("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
|
("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 4)),
|
||||||
("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
|
("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
|
||||||
("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)),
|
("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)),
|
||||||
("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 6)),
|
("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 5)),
|
||||||
("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 7)),
|
("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
|
||||||
("{\"a\":1 1", Error::SyntaxError(ErrorCode::ExpectedObjectCommaOrEnd, 1, 8)),
|
("{\"a\":1 1", Error::SyntaxError(ErrorCode::ExpectedObjectCommaOrEnd, 1, 8)),
|
||||||
("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)),
|
("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 7)),
|
||||||
("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
|
("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -870,8 +870,8 @@ fn test_parse_object() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_struct() {
|
fn test_parse_struct() {
|
||||||
test_parse_err::<Outer>(vec![
|
test_parse_err::<Outer>(vec![
|
||||||
("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
|
("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
|
||||||
("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
|
("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 7)),
|
||||||
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 15)),
|
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 15)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -933,7 +933,7 @@ fn test_parse_option() {
|
|||||||
fn test_parse_enum_errors() {
|
fn test_parse_enum_errors() {
|
||||||
test_parse_err::<Animal>(vec![
|
test_parse_err::<Animal>(vec![
|
||||||
("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
|
("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
|
||||||
("{\"Dog\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)),
|
("{\"Dog\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 7)),
|
||||||
("{\"Dog\":}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
|
("{\"Dog\":}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
|
||||||
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::UnknownField("unknown".to_string()), 1, 11)),
|
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::UnknownField("unknown".to_string()), 1, 11)),
|
||||||
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
|
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
|
||||||
@@ -994,7 +994,7 @@ fn test_parse_trailing_whitespace() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_multiline_errors() {
|
fn test_multiline_errors() {
|
||||||
test_parse_err::<BTreeMap<String, String>>(vec![
|
test_parse_err::<BTreeMap<String, String>>(vec![
|
||||||
("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 8)),
|
("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 6)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1019,3 +1019,26 @@ fn test_missing_field() {
|
|||||||
))).unwrap();
|
))).unwrap();
|
||||||
assert_eq!(value, Foo { x: Some(5) });
|
assert_eq!(value, Foo { x: Some(5) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_missing_renamed_field() {
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
struct Foo {
|
||||||
|
#[serde(rename_deserialize="y")]
|
||||||
|
x: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let value: Foo = from_str("{}").unwrap();
|
||||||
|
assert_eq!(value, Foo { x: None });
|
||||||
|
|
||||||
|
let value: Foo = from_str("{\"y\": 5}").unwrap();
|
||||||
|
assert_eq!(value, Foo { x: Some(5) });
|
||||||
|
|
||||||
|
let value: Foo = from_value(Value::Object(treemap!())).unwrap();
|
||||||
|
assert_eq!(value, Foo { x: None });
|
||||||
|
|
||||||
|
let value: Foo = from_value(Value::Object(treemap!(
|
||||||
|
"y".to_string() => Value::I64(5)
|
||||||
|
))).unwrap();
|
||||||
|
assert_eq!(value, Foo { x: Some(5) });
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user