mirror of
https://codeberg.org/icewind/php-literal-parser.git
synced 2026-06-03 10:34:08 +02:00
use indexmap to preserve array order, implement serialize for Value
This commit is contained in:
parent
5d9cf6de77
commit
3bea91855b
5 changed files with 160 additions and 38 deletions
30
Cargo.lock
generated
30
Cargo.lock
generated
|
|
@ -274,6 +274,12 @@ version = "1.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
@ -306,12 +312,28 @@ dependencies = [
|
||||||
"crunchy",
|
"crunchy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.15.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is-terminal"
|
name = "is-terminal"
|
||||||
version = "0.4.16"
|
version = "0.4.16"
|
||||||
|
|
@ -525,10 +547,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "php-literal-parser"
|
name = "php-literal-parser"
|
||||||
version = "0.6.3"
|
version = "0.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"criterion",
|
"criterion",
|
||||||
|
"indexmap",
|
||||||
"logos",
|
"logos",
|
||||||
"maplit",
|
"maplit",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
@ -536,6 +559,7 @@ dependencies = [
|
||||||
"parse-display",
|
"parse-display",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -690,9 +714,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.132"
|
version = "1.0.142"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
|
checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "php-literal-parser"
|
name = "php-literal-parser"
|
||||||
description = "parser for php literals"
|
description = "parser for php literals"
|
||||||
version = "0.6.3"
|
version = "0.7.0"
|
||||||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
@ -16,6 +16,7 @@ memchr = "2.7.4"
|
||||||
serde = "1.0.214"
|
serde = "1.0.214"
|
||||||
miette = "7.2.0"
|
miette = "7.2.0"
|
||||||
parse-display = "0.9.1"
|
parse-display = "0.9.1"
|
||||||
|
indexmap = "2.10.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
maplit = "1.0.2"
|
maplit = "1.0.2"
|
||||||
|
|
@ -24,6 +25,7 @@ miette = { version = "7.2.0", features = ["fancy"] }
|
||||||
criterion = "0.5.1"
|
criterion = "0.5.1"
|
||||||
clap = "=4.3.24"
|
clap = "=4.3.24"
|
||||||
serde = { version = "1.0.214", features = ["derive"] }
|
serde = { version = "1.0.214", features = ["derive"] }
|
||||||
|
serde_json = "1.0.142"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "parse"
|
name = "parse"
|
||||||
|
|
|
||||||
80
src/lib.rs
80
src/lib.rs
|
|
@ -55,14 +55,16 @@ mod string;
|
||||||
|
|
||||||
use crate::string::is_array_key_numeric;
|
use crate::string::is_array_key_numeric;
|
||||||
pub use error::ParseError;
|
pub use error::ParseError;
|
||||||
|
use indexmap::IndexMap;
|
||||||
use serde::de::{self, MapAccess, SeqAccess, Visitor};
|
use serde::de::{self, MapAccess, SeqAccess, Visitor};
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::ser::{SerializeMap, SerializeSeq};
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
pub use serde_impl::from_str;
|
pub use serde_impl::from_str;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
|
||||||
|
|
@ -78,11 +80,11 @@ use std::ops::Index;
|
||||||
/// or the key is not found
|
/// or the key is not found
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use maplit::hashmap;
|
/// # use indexmap::indexmap;
|
||||||
/// # use php_literal_parser::Value;
|
/// # use php_literal_parser::Value;
|
||||||
/// #
|
/// #
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let value = Value::Array(hashmap!{
|
/// let value = Value::Array(indexmap!{
|
||||||
/// "key".into() => "value".into(),
|
/// "key".into() => "value".into(),
|
||||||
/// 10.into() => false.into()
|
/// 10.into() => false.into()
|
||||||
/// });
|
/// });
|
||||||
|
|
@ -97,7 +99,7 @@ pub enum Value {
|
||||||
Int(i64),
|
Int(i64),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
String(String),
|
String(String),
|
||||||
Array(HashMap<Key, Value>),
|
Array(IndexMap<Key, Value>),
|
||||||
Null,
|
Null,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,8 +166,8 @@ impl Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the value into a hashmap if it is one
|
/// Convert the value into a map if it is one
|
||||||
pub fn into_hashmap(self) -> Option<HashMap<Key, Value>> {
|
pub fn into_map(self) -> Option<IndexMap<Key, Value>> {
|
||||||
match self {
|
match self {
|
||||||
Value::Array(map) => Some(map),
|
Value::Array(map) => Some(map),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
@ -291,9 +293,15 @@ impl From<&str> for Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<IndexMap<Key, Value>> for Value {
|
||||||
|
fn from(value: IndexMap<Key, Value>) -> Self {
|
||||||
|
Value::Array(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<HashMap<Key, Value>> for Value {
|
impl From<HashMap<Key, Value>> for Value {
|
||||||
fn from(value: HashMap<Key, Value>) -> Self {
|
fn from(value: HashMap<Key, Value>) -> Self {
|
||||||
Value::Array(value)
|
Value::Array(value.into_iter().collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -324,6 +332,8 @@ pub enum Key {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hash for Key {
|
impl Hash for Key {
|
||||||
|
// a hash implementation which doesn't include the enum discriminant
|
||||||
|
// that hash hash("foo") == hash(Key::String("foo"))
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
match self {
|
match self {
|
||||||
Key::Int(int) => int.hash(state),
|
Key::Int(int) => int.hash(state),
|
||||||
|
|
@ -350,6 +360,18 @@ impl From<&str> for Key {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Serialize for Key {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Key::Int(i) => serializer.serialize_i64(*i),
|
||||||
|
Key::String(s) => serializer.serialize_str(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Key {
|
impl Key {
|
||||||
/// Check if the key is an integer
|
/// Check if the key is an integer
|
||||||
pub fn is_int(&self) -> bool {
|
pub fn is_int(&self) -> bool {
|
||||||
|
|
@ -487,8 +509,8 @@ impl Display for Key {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_index() {
|
fn test_index() {
|
||||||
use maplit::hashmap;
|
use indexmap::indexmap;
|
||||||
let map = Value::Array(hashmap! {
|
let map = Value::Array(indexmap! {
|
||||||
Key::String("key".to_string()) => Value::String("value".to_string()),
|
Key::String("key".to_string()) => Value::String("value".to_string()),
|
||||||
Key::Int(1) => Value::Bool(true),
|
Key::Int(1) => Value::Bool(true),
|
||||||
});
|
});
|
||||||
|
|
@ -624,7 +646,7 @@ impl<'de> Visitor<'de> for ValueVisitor {
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let mut result = HashMap::new();
|
let mut result = IndexMap::new();
|
||||||
let mut next_key = 0;
|
let mut next_key = 0;
|
||||||
while let Some(value) = seq.next_element::<Value>()? {
|
while let Some(value) = seq.next_element::<Value>()? {
|
||||||
let key = Key::Int(next_key);
|
let key = Key::Int(next_key);
|
||||||
|
|
@ -638,7 +660,7 @@ impl<'de> Visitor<'de> for ValueVisitor {
|
||||||
where
|
where
|
||||||
A: MapAccess<'de>,
|
A: MapAccess<'de>,
|
||||||
{
|
{
|
||||||
let mut result = HashMap::new();
|
let mut result = IndexMap::new();
|
||||||
while let Some((key, value)) = map.next_entry()? {
|
while let Some((key, value)) = map.next_entry()? {
|
||||||
result.insert(key, value);
|
result.insert(key, value);
|
||||||
}
|
}
|
||||||
|
|
@ -655,6 +677,40 @@ impl<'de> Deserialize<'de> for Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Serialize for Value {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Value::Bool(b) => serializer.serialize_bool(*b),
|
||||||
|
Value::Int(i) => serializer.serialize_i64(*i),
|
||||||
|
Value::Float(f) => serializer.serialize_f64(*f),
|
||||||
|
Value::String(s) => serializer.serialize_str(s),
|
||||||
|
Value::Array(a) => {
|
||||||
|
if a.keys()
|
||||||
|
.enumerate()
|
||||||
|
.all(|(i, k)| k.as_int() == Some(i as i64))
|
||||||
|
{
|
||||||
|
let mut seq = serializer.serialize_seq(Some(a.len()))?;
|
||||||
|
for value in a.values() {
|
||||||
|
seq.serialize_element(value)?;
|
||||||
|
}
|
||||||
|
seq.end()
|
||||||
|
} else {
|
||||||
|
let mut map = serializer.serialize_map(Some(a.len()))?;
|
||||||
|
for (key, value) in a {
|
||||||
|
map.serialize_key(key)?;
|
||||||
|
map.serialize_value(value)?;
|
||||||
|
}
|
||||||
|
map.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::Null => serializer.serialize_none(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct KeyVisitor;
|
struct KeyVisitor;
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for KeyVisitor {
|
impl<'de> Visitor<'de> for KeyVisitor {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
use indexmap::indexmap;
|
||||||
use miette::Report;
|
use miette::Report;
|
||||||
use php_literal_parser::from_str;
|
use php_literal_parser::{from_str, Key, Value};
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -92,3 +93,42 @@ pub struct Route {
|
||||||
name: String,
|
name: String,
|
||||||
verb: String,
|
verb: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_value_serde_roundtrip() {
|
||||||
|
fn test_roundtrip(val: Value) {
|
||||||
|
let json = serde_json::to_string(&val).unwrap();
|
||||||
|
let parsed: Value = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(val, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_roundtrip(Value::Bool(false));
|
||||||
|
test_roundtrip(Value::Bool(true));
|
||||||
|
|
||||||
|
test_roundtrip(Value::Int(12));
|
||||||
|
test_roundtrip(Value::Float(12.12));
|
||||||
|
test_roundtrip(Value::String("foo".into()));
|
||||||
|
test_roundtrip(Value::Null);
|
||||||
|
test_roundtrip(Value::Array(indexmap! {
|
||||||
|
Key::Int(0) => Value::Bool(true),
|
||||||
|
Key::Int(1) => Value::Int(12),
|
||||||
|
Key::Int(2) => Value::Int(-12),
|
||||||
|
}));
|
||||||
|
test_roundtrip(Value::Array(indexmap! {
|
||||||
|
Key::Int(1) => Value::Bool(true),
|
||||||
|
Key::Int(2) => Value::Int(12),
|
||||||
|
Key::Int(5) => Value::Int(-12),
|
||||||
|
}));
|
||||||
|
test_roundtrip(Value::Array(indexmap! {
|
||||||
|
Key::String("foo".into()) => Value::Bool(true),
|
||||||
|
Key::String("var".into()) => Value::Array(indexmap! {
|
||||||
|
Key::String("bar".into()) => Value::Bool(true),
|
||||||
|
Key::String("asd".into()) => Value::Int(12),
|
||||||
|
Key::Int(2) => Value::Array(indexmap! {
|
||||||
|
Key::Int(0) => Value::Bool(true),
|
||||||
|
Key::Int(1) => Value::Int(12),
|
||||||
|
Key::Int(2) => Value::Int(-12),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use maplit::hashmap;
|
use indexmap::indexmap;
|
||||||
use php_literal_parser::{from_str, Key, ParseError, Value};
|
use php_literal_parser::{from_str, Key, ParseError, Value};
|
||||||
|
|
||||||
fn parse(source: &str) -> Result<Value, ParseError> {
|
fn parse(source: &str) -> Result<Value, ParseError> {
|
||||||
|
|
@ -22,9 +22,9 @@ fn test_parse_value() {
|
||||||
Value::String("test".to_string()),
|
Value::String("test".to_string()),
|
||||||
parse(r#""test""#).unwrap()
|
parse(r#""test""#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(Value::Array(hashmap! {}), parse(r#"array()"#).unwrap());
|
assert_eq!(Value::Array(indexmap! {}), parse(r#"array()"#).unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(0) => Value::Int(3),
|
Key::Int(0) => Value::Int(3),
|
||||||
Key::Int(1) => Value::Int(4),
|
Key::Int(1) => Value::Int(4),
|
||||||
Key::Int(2) => Value::Int(5),
|
Key::Int(2) => Value::Int(5),
|
||||||
|
|
@ -32,7 +32,7 @@ fn test_parse_value() {
|
||||||
parse(r#"array(3,4,5)"#).unwrap()
|
parse(r#"array(3,4,5)"#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(0) => Value::Int(3),
|
Key::Int(0) => Value::Int(3),
|
||||||
Key::Int(1) => Value::Int(4),
|
Key::Int(1) => Value::Int(4),
|
||||||
Key::Int(2) => Value::Int(5),
|
Key::Int(2) => Value::Int(5),
|
||||||
|
|
@ -40,7 +40,7 @@ fn test_parse_value() {
|
||||||
parse(r#"array(3,4,5,)"#).unwrap()
|
parse(r#"array(3,4,5,)"#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(1) => Value::Int(3),
|
Key::Int(1) => Value::Int(3),
|
||||||
Key::Int(3) => Value::Int(4),
|
Key::Int(3) => Value::Int(4),
|
||||||
Key::Int(5) => Value::Int(5),
|
Key::Int(5) => Value::Int(5),
|
||||||
|
|
@ -48,7 +48,7 @@ fn test_parse_value() {
|
||||||
parse(r#"array(1=>3,3=>4,5=>5)"#).unwrap()
|
parse(r#"array(1=>3,3=>4,5=>5)"#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(1) => Value::Int(3),
|
Key::Int(1) => Value::Int(3),
|
||||||
Key::Int(2) => Value::Int(4),
|
Key::Int(2) => Value::Int(4),
|
||||||
Key::Int(3) => Value::Int(5),
|
Key::Int(3) => Value::Int(5),
|
||||||
|
|
@ -56,7 +56,7 @@ fn test_parse_value() {
|
||||||
parse(r#"array(1=>3,4,5)"#).unwrap()
|
parse(r#"array(1=>3,4,5)"#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(1) => Value::Int(3),
|
Key::Int(1) => Value::Int(3),
|
||||||
Key::Int(2) => Value::Int(4),
|
Key::Int(2) => Value::Int(4),
|
||||||
Key::Int(3) => Value::Int(5),
|
Key::Int(3) => Value::Int(5),
|
||||||
|
|
@ -64,7 +64,7 @@ fn test_parse_value() {
|
||||||
parse(r#"array("1"=>3,4,5)"#).unwrap()
|
parse(r#"array("1"=>3,4,5)"#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(1) => Value::Int(3),
|
Key::Int(1) => Value::Int(3),
|
||||||
Key::Int(2) => Value::Int(4),
|
Key::Int(2) => Value::Int(4),
|
||||||
Key::Int(3) => Value::Int(5),
|
Key::Int(3) => Value::Int(5),
|
||||||
|
|
@ -72,7 +72,7 @@ fn test_parse_value() {
|
||||||
parse(r#"array(1.5=>3,4,5)"#).unwrap()
|
parse(r#"array(1.5=>3,4,5)"#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(1) => Value::Int(3),
|
Key::Int(1) => Value::Int(3),
|
||||||
Key::Int(2) => Value::Int(4),
|
Key::Int(2) => Value::Int(4),
|
||||||
Key::Int(3) => Value::Int(5),
|
Key::Int(3) => Value::Int(5),
|
||||||
|
|
@ -80,7 +80,7 @@ fn test_parse_value() {
|
||||||
parse(r#"array(true=>3,4,5)"#).unwrap()
|
parse(r#"array(true=>3,4,5)"#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(1) => Value::Int(3),
|
Key::Int(1) => Value::Int(3),
|
||||||
Key::String("foo".into()) => Value::Int(4),
|
Key::String("foo".into()) => Value::Int(4),
|
||||||
Key::Int(2) => Value::Int(5),
|
Key::Int(2) => Value::Int(5),
|
||||||
|
|
@ -88,18 +88,18 @@ fn test_parse_value() {
|
||||||
parse(r#"array(1=>3,"foo" => 4,5)"#).unwrap()
|
parse(r#"array(1=>3,"foo" => 4,5)"#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::String("foo".into()) => Value::Bool(true),
|
Key::String("foo".into()) => Value::Bool(true),
|
||||||
Key::String("nested".into()) => Value::Array(hashmap! {
|
Key::String("nested".into()) => Value::Array(indexmap! {
|
||||||
Key::String("foo".into()) => Value::Bool(false),
|
Key::String("foo".into()) => Value::Bool(false),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
parse(r#"array("foo" => true, "nested" => array ('foo' => false))"#).unwrap()
|
parse(r#"array("foo" => true, "nested" => array ('foo' => false))"#).unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::String("foo".into()) => Value::Bool(true),
|
Key::String("foo".into()) => Value::Bool(true),
|
||||||
Key::String("nested".into()) => Value::Array(hashmap! {
|
Key::String("nested".into()) => Value::Array(indexmap! {
|
||||||
Key::String("foo".into()) => Value::Null,
|
Key::String("foo".into()) => Value::Null,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
@ -120,7 +120,7 @@ fn test_parse_value() {
|
||||||
assert_eq!(Value::Float(1234.5), parse(r#"12_34.5"#).unwrap());
|
assert_eq!(Value::Float(1234.5), parse(r#"12_34.5"#).unwrap());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(2) => Value::Int(3),
|
Key::Int(2) => Value::Int(3),
|
||||||
Key::String("foo".into()) => Value::Int(4),
|
Key::String("foo".into()) => Value::Int(4),
|
||||||
Key::String("".into()) => Value::Int(5),
|
Key::String("".into()) => Value::Int(5),
|
||||||
|
|
@ -131,11 +131,11 @@ fn test_parse_value() {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(0) => hashmap! {
|
Key::Int(0) => indexmap! {
|
||||||
Key::String("a".into()) => Value::Int(2),
|
Key::String("a".into()) => Value::Int(2),
|
||||||
}.into(),
|
}.into(),
|
||||||
Key::Int(1) => hashmap! {
|
Key::Int(1) => indexmap! {
|
||||||
Key::String("b".into()) => Value::Int(3),
|
Key::String("b".into()) => Value::Int(3),
|
||||||
}.into()
|
}.into()
|
||||||
}),
|
}),
|
||||||
|
|
@ -143,11 +143,11 @@ fn test_parse_value() {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Value::Array(hashmap! {
|
Value::Array(indexmap! {
|
||||||
Key::Int(0) => hashmap! {
|
Key::Int(0) => indexmap! {
|
||||||
Key::String("a".into()) => Value::Int(2),
|
Key::String("a".into()) => Value::Int(2),
|
||||||
}.into(),
|
}.into(),
|
||||||
Key::Int(1) => hashmap! {
|
Key::Int(1) => indexmap! {
|
||||||
Key::String("b".into()) => Value::Int(3),
|
Key::String("b".into()) => Value::Int(3),
|
||||||
}.into()
|
}.into()
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue