Docs, json::Value::U64, and bring many of the rust-serialize fns to Value
This commit is contained in:
parent
eb4af09456
commit
8821421357
@ -130,17 +130,16 @@ impl<Iter> Deserializer<Iter>
|
|||||||
fn parse_number<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
fn parse_number<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||||
where V: de::Visitor,
|
where V: de::Visitor,
|
||||||
{
|
{
|
||||||
let mut neg = 1;
|
let mut neg = false;
|
||||||
|
|
||||||
if self.ch_is(b'-') {
|
if self.ch_is(b'-') {
|
||||||
self.bump();
|
self.bump();
|
||||||
neg = -1;
|
neg = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = try!(self.parse_integer());
|
let res = try!(self.parse_integer());
|
||||||
|
|
||||||
if self.ch_is(b'.') || self.ch_is(b'e') || self.ch_is(b'E') {
|
if self.ch_is(b'.') || self.ch_is(b'e') || self.ch_is(b'E') {
|
||||||
let neg = neg as f64;
|
|
||||||
let mut res = res as f64;
|
let mut res = res as f64;
|
||||||
|
|
||||||
if self.ch_is(b'.') {
|
if self.ch_is(b'.') {
|
||||||
@ -151,13 +150,28 @@ impl<Iter> Deserializer<Iter>
|
|||||||
res = try!(self.parse_exponent(res));
|
res = try!(self.parse_exponent(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
visitor.visit_f64(neg * res)
|
if neg {
|
||||||
|
visitor.visit_f64(-res)
|
||||||
} else {
|
} else {
|
||||||
visitor.visit_i64(neg * res)
|
visitor.visit_f64(res)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if neg {
|
||||||
|
let res = -(res as i64);
|
||||||
|
|
||||||
|
// Make sure we didn't underflow.
|
||||||
|
if res > 0 {
|
||||||
|
Err(self.error(ErrorCode::InvalidNumber))
|
||||||
|
} else {
|
||||||
|
visitor.visit_i64(res)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
visitor.visit_u64(res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_integer(&mut self) -> Result<i64, Error> {
|
fn parse_integer(&mut self) -> Result<u64, Error> {
|
||||||
let mut res = 0;
|
let mut res = 0;
|
||||||
|
|
||||||
match self.ch_or_null() {
|
match self.ch_or_null() {
|
||||||
@ -177,7 +191,7 @@ impl<Iter> Deserializer<Iter>
|
|||||||
match self.ch_or_null() {
|
match self.ch_or_null() {
|
||||||
c @ b'0' ... b'9' => {
|
c @ b'0' ... b'9' => {
|
||||||
res *= 10;
|
res *= 10;
|
||||||
res += (c as i64) - (b'0' as i64);
|
res += (c as u64) - (b'0' as u64);
|
||||||
self.bump();
|
self.bump();
|
||||||
}
|
}
|
||||||
_ => break,
|
_ => break,
|
||||||
|
132
src/json/mod.rs
132
src/json/mod.rs
@ -1,3 +1,135 @@
|
|||||||
|
//! JSON and serialization
|
||||||
|
//!
|
||||||
|
//! # What is JSON?
|
||||||
|
//!
|
||||||
|
//! JSON (JavaScript Object Notation) is a way to write data in JavaScript. Like XML, it allows to
|
||||||
|
//! encode structured data in a text format that can be easily read by humans. Its simple syntax
|
||||||
|
//! and native compatibility with JavaScript have made it a widely used format.
|
||||||
|
//!
|
||||||
|
//! Data types that can be encoded are JavaScript types (see the `serde::json:Value` enum for more
|
||||||
|
//! details):
|
||||||
|
//!
|
||||||
|
//! * `Boolean`: equivalent to rust's `bool`
|
||||||
|
//! * `I64`: equivalent to rust's `i64`
|
||||||
|
//! * `U64`: equivalent to rust's `u64`
|
||||||
|
//! * `F64`: equivalent to rust's `i64`
|
||||||
|
//! * `String`: equivalent to rust's `String`
|
||||||
|
//! * `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the
|
||||||
|
//! same array
|
||||||
|
//! * `Object`: equivalent to rust's `BTreeMap<String, serde::json::Value>`
|
||||||
|
//! * `Null`
|
||||||
|
//!
|
||||||
|
//! An object is a series of string keys mapping to values, in `"key": value` format. Arrays are
|
||||||
|
//! enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). A simple JSON
|
||||||
|
//! document encoding a person, his/her age, address and phone numbers could look like
|
||||||
|
//!
|
||||||
|
//! ```ignore
|
||||||
|
//! {
|
||||||
|
//! "FirstName": "John",
|
||||||
|
//! "LastName": "Doe",
|
||||||
|
//! "Age": 43,
|
||||||
|
//! "Address": {
|
||||||
|
//! "Street": "Downing Street 10",
|
||||||
|
//! "City": "London",
|
||||||
|
//! "Country": "Great Britain"
|
||||||
|
//! },
|
||||||
|
//! "PhoneNumbers": [
|
||||||
|
//! "+44 1234567",
|
||||||
|
//! "+44 2345678"
|
||||||
|
//! ]
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! # Type-based Serialization and Deserialization
|
||||||
|
//!
|
||||||
|
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
|
||||||
|
//! from JSON via the serialization API. To be able to serialize a piece of data, it must implement
|
||||||
|
//! the `serde::Serialize` trait. To be able to deserialize a piece of data, it must implement the
|
||||||
|
//! `serde::Deserialize` trait. Serde provides provides an annotation to automatically generate
|
||||||
|
//! the code for these traits: `#[derive_serialize]` and `#[derive_deserialize]`.
|
||||||
|
//!
|
||||||
|
//! The JSON API also provides an enum `serde::json::Value` and a method `to_value` to serialize
|
||||||
|
//! objects. A `serde::json::Value` value can be serialized as a string or buffer using the
|
||||||
|
//! functions described above. You can also use the `json::Encoder` object, which implements the
|
||||||
|
//! `Encoder` trait.
|
||||||
|
//!
|
||||||
|
//! # Examples of use
|
||||||
|
//!
|
||||||
|
//! ## Using Autoserialization
|
||||||
|
//!
|
||||||
|
//! Create a struct called `TestStruct` and serialize and deserialize it to and from JSON using the
|
||||||
|
//! serialization API, using the derived serialization code.
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! // Required to use the annotations.
|
||||||
|
//! #![feature(custom_derive, plugin)]
|
||||||
|
//! #![plugin(serde_macros)]
|
||||||
|
//!
|
||||||
|
//! extern crate serde;
|
||||||
|
//!
|
||||||
|
//! use serde::json;
|
||||||
|
//!
|
||||||
|
//! // Automatically generate `Serialize` and `Deserialize` trait implementations
|
||||||
|
//! #[derive_serialize]
|
||||||
|
//! #[derive_deserialize]
|
||||||
|
//! pub struct TestStruct {
|
||||||
|
//! data_int: u8,
|
||||||
|
//! data_str: String,
|
||||||
|
//! data_vector: Vec<u8>,
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! fn main() {
|
||||||
|
//! let object = TestStruct {
|
||||||
|
//! data_int: 1,
|
||||||
|
//! data_str: "homura".to_string(),
|
||||||
|
//! data_vector: vec![2,3,4,5],
|
||||||
|
//! };
|
||||||
|
//!
|
||||||
|
//! // Serialize using `json::to_string`
|
||||||
|
//! let serialized = json::to_string(&object).unwrap();
|
||||||
|
//!
|
||||||
|
//! // Deserialize using `json::from_str`
|
||||||
|
//! let deserialized: TestStruct = json::from_str(&serialized).unwrap();
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! ## Parsing a `str` to `Value` and reading the result
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! #![feature(custom_derive, plugin)]
|
||||||
|
//! #![plugin(serde_macros)]
|
||||||
|
//!
|
||||||
|
//! extern crate serde;
|
||||||
|
//!
|
||||||
|
//! use serde::json::{self, Value};
|
||||||
|
//!
|
||||||
|
//! fn main() {
|
||||||
|
//! let data: Value = json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
|
||||||
|
//! println!("data: {:?}", data);
|
||||||
|
//! // data: {"bar":"baz","foo":13}
|
||||||
|
//! println!("object? {}", data.is_object());
|
||||||
|
//! // object? true
|
||||||
|
//!
|
||||||
|
//! let obj = data.as_object().unwrap();
|
||||||
|
//! let foo = obj.get("foo").unwrap();
|
||||||
|
//!
|
||||||
|
//! println!("array? {:?}", foo.as_array());
|
||||||
|
//! // array? None
|
||||||
|
//! println!("u64? {:?}", foo.as_u64());
|
||||||
|
//! // u64? Some(13u64)
|
||||||
|
//!
|
||||||
|
//! for (key, value) in obj.iter() {
|
||||||
|
//! println!("{}: {}", key, match *value {
|
||||||
|
//! Value::U64(v) => format!("{} (u64)", v),
|
||||||
|
//! Value::String(ref v) => format!("{} (string)", v),
|
||||||
|
//! _ => format!("other")
|
||||||
|
//! });
|
||||||
|
//! }
|
||||||
|
//! // bar: baz (string)
|
||||||
|
//! // foo: 13 (u64)
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
|
||||||
pub use self::de::{Deserializer, from_str};
|
pub use self::de::{Deserializer, from_str};
|
||||||
pub use self::error::{Error, ErrorCode};
|
pub use self::error::{Error, ErrorCode};
|
||||||
pub use self::ser::{
|
pub use self::ser::{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::collections::{BTreeMap, btree_map};
|
use std::collections::{BTreeMap, btree_map};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::num;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
@ -13,12 +14,212 @@ pub enum Value {
|
|||||||
Null,
|
Null,
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
I64(i64),
|
I64(i64),
|
||||||
|
U64(u64),
|
||||||
F64(f64),
|
F64(f64),
|
||||||
String(String),
|
String(String),
|
||||||
Array(Vec<Value>),
|
Array(Vec<Value>),
|
||||||
Object(BTreeMap<String, Value>),
|
Object(BTreeMap<String, Value>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Value {
|
||||||
|
/// If the `Value` is an Object, returns the value associated with the provided key.
|
||||||
|
/// Otherwise, returns None.
|
||||||
|
pub fn find<'a>(&'a self, key: &str) -> Option<&'a Value>{
|
||||||
|
match self {
|
||||||
|
&Value::Object(ref map) => map.get(key),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempts to get a nested Value Object for each key in `keys`.
|
||||||
|
/// If any key is found not to exist, find_path will return None.
|
||||||
|
/// Otherwise, it will return the `Value` associated with the final key.
|
||||||
|
pub fn find_path<'a>(&'a self, keys: &[&str]) -> Option<&'a Value>{
|
||||||
|
let mut target = self;
|
||||||
|
for key in keys.iter() {
|
||||||
|
match target.find(*key) {
|
||||||
|
Some(t) => { target = t; },
|
||||||
|
None => return None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is an Object, performs a depth-first search until
|
||||||
|
/// a value associated with the provided key is found. If no value is found
|
||||||
|
/// or the `Value` is not an Object, returns None.
|
||||||
|
pub fn search<'a>(&'a self, key: &str) -> Option<&'a Value> {
|
||||||
|
match self {
|
||||||
|
&Value::Object(ref map) => {
|
||||||
|
match map.get(key) {
|
||||||
|
Some(json_value) => Some(json_value),
|
||||||
|
None => {
|
||||||
|
for (_, v) in map.iter() {
|
||||||
|
match v.search(key) {
|
||||||
|
x if x.is_some() => return x,
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `Value` is an Object. Returns false otherwise.
|
||||||
|
pub fn is_object<'a>(&'a self) -> bool {
|
||||||
|
self.as_object().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is an Object, returns the associated BTreeMap.
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_object<'a>(&'a self) -> Option<&'a BTreeMap<String, Value>> {
|
||||||
|
match self {
|
||||||
|
&Value::Object(ref map) => Some(map),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is an Object, returns the associated mutable BTreeMap.
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_object_mut<'a>(&'a mut self) -> Option<&'a mut BTreeMap<String, Value>> {
|
||||||
|
match self {
|
||||||
|
&mut Value::Object(ref mut map) => Some(map),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `Value` is an Array. Returns false otherwise.
|
||||||
|
pub fn is_array<'a>(&'a self) -> bool {
|
||||||
|
self.as_array().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is an Array, returns the associated vector.
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_array<'a>(&'a self) -> Option<&'a Vec<Value>> {
|
||||||
|
match self {
|
||||||
|
&Value::Array(ref array) => Some(&*array),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is an Array, returns the associated mutable vector.
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_array_mut<'a>(&'a mut self) -> Option<&'a mut Vec<Value>> {
|
||||||
|
match self {
|
||||||
|
&mut Value::Array(ref mut list) => Some(list),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `Value` is a String. Returns false otherwise.
|
||||||
|
pub fn is_string<'a>(&'a self) -> bool {
|
||||||
|
self.as_string().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is a String, returns the associated str.
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_string<'a>(&'a self) -> Option<&'a str> {
|
||||||
|
match *self {
|
||||||
|
Value::String(ref s) => Some(&s),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `Value` is a Number. Returns false otherwise.
|
||||||
|
pub fn is_number(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Value::I64(_) | Value::U64(_) | Value::F64(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `Value` is a i64. Returns false otherwise.
|
||||||
|
pub fn is_i64(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Value::I64(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `Value` is a u64. Returns false otherwise.
|
||||||
|
pub fn is_u64(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Value::U64(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `Value` is a f64. Returns false otherwise.
|
||||||
|
pub fn is_f64(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Value::F64(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is a number, return or cast it to a i64.
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_i64(&self) -> Option<i64> {
|
||||||
|
match *self {
|
||||||
|
Value::I64(n) => Some(n),
|
||||||
|
Value::U64(n) => num::cast(n),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is a number, return or cast it to a u64.
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_u64(&self) -> Option<u64> {
|
||||||
|
match *self {
|
||||||
|
Value::I64(n) => num::cast(n),
|
||||||
|
Value::U64(n) => Some(n),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is a number, return or cast it to a f64.
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_f64(&self) -> Option<f64> {
|
||||||
|
match *self {
|
||||||
|
Value::I64(n) => num::cast(n),
|
||||||
|
Value::U64(n) => num::cast(n),
|
||||||
|
Value::F64(n) => Some(n),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `Value` is a Boolean. Returns false otherwise.
|
||||||
|
pub fn is_boolean(&self) -> bool {
|
||||||
|
self.as_boolean().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is a Boolean, returns the associated bool.
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_boolean(&self) -> Option<bool> {
|
||||||
|
match self {
|
||||||
|
&Value::Bool(b) => Some(b),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the `Value` is a Null. Returns false otherwise.
|
||||||
|
pub fn is_null(&self) -> bool {
|
||||||
|
self.as_null().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the `Value` is a Null, returns ().
|
||||||
|
/// Returns None otherwise.
|
||||||
|
pub fn as_null(&self) -> Option<()> {
|
||||||
|
match self {
|
||||||
|
&Value::Null => Some(()),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ser::Serialize for Value {
|
impl ser::Serialize for Value {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
@ -28,6 +229,7 @@ impl ser::Serialize for Value {
|
|||||||
Value::Null => serializer.visit_unit(),
|
Value::Null => serializer.visit_unit(),
|
||||||
Value::Bool(v) => serializer.visit_bool(v),
|
Value::Bool(v) => serializer.visit_bool(v),
|
||||||
Value::I64(v) => serializer.visit_i64(v),
|
Value::I64(v) => serializer.visit_i64(v),
|
||||||
|
Value::U64(v) => serializer.visit_u64(v),
|
||||||
Value::F64(v) => serializer.visit_f64(v),
|
Value::F64(v) => serializer.visit_f64(v),
|
||||||
Value::String(ref v) => serializer.visit_str(&v),
|
Value::String(ref v) => serializer.visit_str(&v),
|
||||||
Value::Array(ref v) => v.serialize(serializer),
|
Value::Array(ref v) => v.serialize(serializer),
|
||||||
@ -53,7 +255,16 @@ impl de::Deserialize for Value {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
|
fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
|
||||||
|
if value < 0 {
|
||||||
Ok(Value::I64(value))
|
Ok(Value::I64(value))
|
||||||
|
} else {
|
||||||
|
Ok(Value::U64(value as u64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_u64<E>(&mut self, value: u64) -> Result<Value, E> {
|
||||||
|
Ok(Value::U64(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -173,13 +384,17 @@ impl ser::Serializer for Serializer {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_i64(&mut self, value: i64) -> Result<(), ()> {
|
fn visit_i64(&mut self, value: i64) -> Result<(), ()> {
|
||||||
|
if value < 0 {
|
||||||
self.state.push(State::Value(Value::I64(value)));
|
self.state.push(State::Value(Value::I64(value)));
|
||||||
|
} else {
|
||||||
|
self.state.push(State::Value(Value::U64(value as u64)));
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_u64(&mut self, value: u64) -> Result<(), ()> {
|
fn visit_u64(&mut self, value: u64) -> Result<(), ()> {
|
||||||
self.state.push(State::Value(Value::I64(value as i64)));
|
self.state.push(State::Value(Value::U64(value)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,6 +601,7 @@ impl de::Deserializer for Deserializer {
|
|||||||
Value::Null => visitor.visit_unit(),
|
Value::Null => visitor.visit_unit(),
|
||||||
Value::Bool(v) => visitor.visit_bool(v),
|
Value::Bool(v) => visitor.visit_bool(v),
|
||||||
Value::I64(v) => visitor.visit_i64(v),
|
Value::I64(v) => visitor.visit_i64(v),
|
||||||
|
Value::U64(v) => visitor.visit_u64(v),
|
||||||
Value::F64(v) => visitor.visit_f64(v),
|
Value::F64(v) => visitor.visit_f64(v),
|
||||||
Value::String(v) => visitor.visit_string(v),
|
Value::String(v) => visitor.visit_string(v),
|
||||||
Value::Array(v) => {
|
Value::Array(v) => {
|
||||||
|
@ -711,13 +711,20 @@ fn test_parse_number_errors() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_i64() {
|
fn test_parse_i64() {
|
||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
("3", 3),
|
|
||||||
("-2", -2),
|
("-2", -2),
|
||||||
("-1234", -1234),
|
("-1234", -1234),
|
||||||
(" -1234 ", -1234),
|
(" -1234 ", -1234),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_u64() {
|
||||||
|
test_parse_ok(vec![
|
||||||
|
("3", 3u64),
|
||||||
|
("1234", 1234),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_f64() {
|
fn test_parse_f64() {
|
||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
@ -778,28 +785,28 @@ fn test_parse_list() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
("[3,1]", vec![3, 1]),
|
("[3,1]", vec![3u64, 1]),
|
||||||
(" [ 3 , 1 ] ", vec![3, 1]),
|
(" [ 3 , 1 ] ", vec![3, 1]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
("[[3], [1, 2]]", vec![vec![3], vec![1, 2]]),
|
("[[3], [1, 2]]", vec![vec![3u64], vec![1, 2]]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
("[1]", (1,)),
|
("[1]", (1u64,)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
("[1, 2]", (1, 2)),
|
("[1, 2]", (1u64, 2u64)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
("[1, 2, 3]", (1, 2, 3)),
|
("[1, 2, 3]", (1u64, 2u64, 3u64)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
("[1, [2, 3]]", (1, (2, 3))),
|
("[1, [2, 3]]", (1u64, (2u64, 3u64))),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let v: () = from_str("[]").unwrap();
|
let v: () = from_str("[]").unwrap();
|
||||||
@ -828,7 +835,7 @@ fn test_parse_object() {
|
|||||||
("{ }", treemap!()),
|
("{ }", treemap!()),
|
||||||
(
|
(
|
||||||
"{\"a\":3}",
|
"{\"a\":3}",
|
||||||
treemap!("a".to_string() => 3)
|
treemap!("a".to_string() => 3u64)
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"{ \"a\" : 3 }",
|
"{ \"a\" : 3 }",
|
||||||
@ -847,7 +854,12 @@ fn test_parse_object() {
|
|||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
(
|
(
|
||||||
"{\"a\": {\"b\": 3, \"c\": 4}}",
|
"{\"a\": {\"b\": 3, \"c\": 4}}",
|
||||||
treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)),
|
treemap!(
|
||||||
|
"a".to_string() => treemap!(
|
||||||
|
"b".to_string() => 3u64,
|
||||||
|
"c".to_string() => 4
|
||||||
|
)
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -962,7 +974,7 @@ fn test_parse_enum() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_trailing_whitespace() {
|
fn test_parse_trailing_whitespace() {
|
||||||
test_parse_ok(vec![
|
test_parse_ok(vec![
|
||||||
("[1, 2] ", vec![1, 2]),
|
("[1, 2] ", vec![1u64, 2]),
|
||||||
("[1, 2]\n", vec![1, 2]),
|
("[1, 2]\n", vec![1, 2]),
|
||||||
("[1, 2]\t", vec![1, 2]),
|
("[1, 2]\t", vec![1, 2]),
|
||||||
("[1, 2]\t \n", vec![1, 2]),
|
("[1, 2]\t \n", vec![1, 2]),
|
||||||
|
@ -15,12 +15,12 @@ fn test_array_builder() {
|
|||||||
.push(2)
|
.push(2)
|
||||||
.push(3)
|
.push(3)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(value, Value::Array(vec!(Value::I64(1), Value::I64(2), Value::I64(3))));
|
assert_eq!(value, Value::Array(vec!(Value::U64(1), Value::U64(2), Value::U64(3))));
|
||||||
|
|
||||||
let value = ArrayBuilder::new()
|
let value = ArrayBuilder::new()
|
||||||
.push_array(|bld| bld.push(1).push(2).push(3))
|
.push_array(|bld| bld.push(1).push(2).push(3))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::I64(1), Value::I64(2), Value::I64(3))))));
|
assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::U64(1), Value::U64(2), Value::U64(3))))));
|
||||||
|
|
||||||
let value = ArrayBuilder::new()
|
let value = ArrayBuilder::new()
|
||||||
.push_object(|bld|
|
.push_object(|bld|
|
||||||
@ -30,8 +30,8 @@ fn test_array_builder() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut map = BTreeMap::new();
|
let mut map = BTreeMap::new();
|
||||||
map.insert("a".to_string(), Value::I64(1));
|
map.insert("a".to_string(), Value::U64(1));
|
||||||
map.insert("b".to_string(), Value::I64(2));
|
map.insert("b".to_string(), Value::U64(2));
|
||||||
assert_eq!(value, Value::Array(vec!(Value::Object(map))));
|
assert_eq!(value, Value::Array(vec!(Value::Object(map))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ fn test_object_builder() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut map = BTreeMap::new();
|
let mut map = BTreeMap::new();
|
||||||
map.insert("a".to_string(), Value::I64(1));
|
map.insert("a".to_string(), Value::U64(1));
|
||||||
map.insert("b".to_string(), Value::I64(2));
|
map.insert("b".to_string(), Value::U64(2));
|
||||||
assert_eq!(value, Value::Object(map));
|
assert_eq!(value, Value::Object(map));
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ fn test_ser_named_tuple() {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
json::to_value(&named_tuple),
|
json::to_value(&named_tuple),
|
||||||
Value::Array(vec![Value::I64(5), Value::I64(6), Value::I64(7)])
|
Value::Array(vec![Value::U64(5), Value::U64(6), Value::U64(7)])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,9 +185,9 @@ fn test_de_named_tuple() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
json::from_str("[1,2,3]").unwrap(),
|
json::from_str("[1,2,3]").unwrap(),
|
||||||
Value::Array(vec![
|
Value::Array(vec![
|
||||||
Value::I64(1),
|
Value::U64(1),
|
||||||
Value::I64(2),
|
Value::U64(2),
|
||||||
Value::I64(3),
|
Value::U64(3),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -211,9 +211,9 @@ fn test_ser_named_map() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
json::to_value(&named_map),
|
json::to_value(&named_map),
|
||||||
Value::Object(btreemap![
|
Value::Object(btreemap![
|
||||||
"a".to_string() => Value::I64(5),
|
"a".to_string() => Value::U64(5),
|
||||||
"b".to_string() => Value::I64(6),
|
"b".to_string() => Value::U64(6),
|
||||||
"c".to_string() => Value::I64(7)
|
"c".to_string() => Value::U64(7)
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -233,9 +233,9 @@ fn test_de_named_map() {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
json::from_value(Value::Object(btreemap![
|
json::from_value(Value::Object(btreemap![
|
||||||
"a".to_string() => Value::I64(5),
|
"a".to_string() => Value::U64(5),
|
||||||
"b".to_string() => Value::I64(6),
|
"b".to_string() => Value::U64(6),
|
||||||
"c".to_string() => Value::I64(7)
|
"c".to_string() => Value::U64(7)
|
||||||
])).unwrap(),
|
])).unwrap(),
|
||||||
v
|
v
|
||||||
);
|
);
|
||||||
@ -288,12 +288,12 @@ fn test_ser_enum_seq() {
|
|||||||
)),
|
)),
|
||||||
Value::Object(btreemap!(
|
Value::Object(btreemap!(
|
||||||
"Seq".to_string() => Value::Array(vec![
|
"Seq".to_string() => Value::Array(vec![
|
||||||
Value::I64(1),
|
Value::U64(1),
|
||||||
Value::I64(2),
|
Value::U64(2),
|
||||||
Value::I64(3),
|
Value::U64(3),
|
||||||
//Value::I64(4),
|
//Value::U64(4),
|
||||||
Value::I64(5),
|
Value::U64(5),
|
||||||
//Value::I64(6),
|
//Value::U64(6),
|
||||||
])
|
])
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
@ -331,12 +331,12 @@ fn test_ser_enum_map() {
|
|||||||
}),
|
}),
|
||||||
Value::Object(btreemap!(
|
Value::Object(btreemap!(
|
||||||
"Map".to_string() => Value::Object(btreemap![
|
"Map".to_string() => Value::Object(btreemap![
|
||||||
"a".to_string() => Value::I64(1),
|
"a".to_string() => Value::U64(1),
|
||||||
"b".to_string() => Value::I64(2),
|
"b".to_string() => Value::U64(2),
|
||||||
"c".to_string() => Value::I64(3),
|
"c".to_string() => Value::U64(3),
|
||||||
//"d".to_string() => Value::I64(4)
|
//"d".to_string() => Value::U64(4)
|
||||||
"e".to_string() => Value::I64(5)
|
"e".to_string() => Value::U64(5)
|
||||||
//"f".to_string() => Value::I64(6)
|
//"f".to_string() => Value::U64(6)
|
||||||
])
|
])
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
@ -381,12 +381,12 @@ fn test_de_enum_seq() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
json::from_value(Value::Object(btreemap!(
|
json::from_value(Value::Object(btreemap!(
|
||||||
"Seq".to_string() => Value::Array(vec![
|
"Seq".to_string() => Value::Array(vec![
|
||||||
Value::I64(1),
|
Value::U64(1),
|
||||||
Value::I64(2),
|
Value::U64(2),
|
||||||
Value::I64(3),
|
Value::U64(3),
|
||||||
//Value::I64(4),
|
//Value::U64(4),
|
||||||
Value::I64(5),
|
Value::U64(5),
|
||||||
//Value::I64(6),
|
//Value::U64(6),
|
||||||
])
|
])
|
||||||
))).unwrap(),
|
))).unwrap(),
|
||||||
DeEnum::Seq(
|
DeEnum::Seq(
|
||||||
@ -424,12 +424,12 @@ fn test_de_enum_map() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
json::from_value(Value::Object(btreemap!(
|
json::from_value(Value::Object(btreemap!(
|
||||||
"Map".to_string() => Value::Object(btreemap![
|
"Map".to_string() => Value::Object(btreemap![
|
||||||
"a".to_string() => Value::I64(1),
|
"a".to_string() => Value::U64(1),
|
||||||
"b".to_string() => Value::I64(2),
|
"b".to_string() => Value::U64(2),
|
||||||
"c".to_string() => Value::I64(3),
|
"c".to_string() => Value::U64(3),
|
||||||
//"d".to_string() => Value::I64(4)
|
//"d".to_string() => Value::U64(4)
|
||||||
"e".to_string() => Value::I64(5)
|
"e".to_string() => Value::U64(5)
|
||||||
//"f".to_string() => Value::I64(6)
|
//"f".to_string() => Value::U64(6)
|
||||||
])
|
])
|
||||||
))).unwrap(),
|
))).unwrap(),
|
||||||
DeEnum::Map {
|
DeEnum::Map {
|
||||||
|
Loading…
Reference in New Issue
Block a user