2017-01-25 18:51:41 +01:00
|
|
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
2016-07-05 15:16:27 +02:00
|
|
|
// This file is part of Parity.
|
|
|
|
|
|
|
|
// Parity is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
|
|
|
// Parity is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
//! Trie test input deserialization.
|
|
|
|
|
2017-02-13 16:38:47 +01:00
|
|
|
use std::fmt;
|
2016-07-05 15:16:27 +02:00
|
|
|
use std::collections::BTreeMap;
|
|
|
|
use std::str::FromStr;
|
|
|
|
use bytes::Bytes;
|
2017-02-13 16:38:47 +01:00
|
|
|
use serde::{Deserialize, Deserializer};
|
2017-07-06 11:36:15 +02:00
|
|
|
use serde::de::{Error as ErrorTrait, Visitor, MapAccess, SeqAccess};
|
2016-07-05 15:16:27 +02:00
|
|
|
|
|
|
|
/// Trie test input.
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub struct Input {
|
|
|
|
/// Input params.
|
|
|
|
pub data: BTreeMap<Bytes, Option<Bytes>>,
|
|
|
|
}
|
|
|
|
|
2017-07-06 11:36:15 +02:00
|
|
|
impl<'a> Deserialize<'a> for Input {
|
2017-02-13 16:38:47 +01:00
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
2017-07-06 11:36:15 +02:00
|
|
|
where D: Deserializer<'a>
|
2016-07-05 15:16:27 +02:00
|
|
|
{
|
2017-07-06 11:36:15 +02:00
|
|
|
deserializer.deserialize_any(InputVisitor)
|
2016-07-05 15:16:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct InputVisitor;
|
|
|
|
|
2017-07-06 11:36:15 +02:00
|
|
|
impl<'a> Visitor<'a> for InputVisitor {
|
2016-07-05 15:16:27 +02:00
|
|
|
type Value = Input;
|
|
|
|
|
2017-02-13 16:38:47 +01:00
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(formatter, "a map of bytes into bytes")
|
|
|
|
}
|
|
|
|
|
2017-07-06 11:36:15 +02:00
|
|
|
fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> where V: MapAccess<'a> {
|
2016-07-05 15:16:27 +02:00
|
|
|
let mut result = BTreeMap::new();
|
|
|
|
|
|
|
|
loop {
|
2017-07-06 11:36:15 +02:00
|
|
|
let key_str: Option<String> = visitor.next_key()?;
|
2016-07-05 15:16:27 +02:00
|
|
|
let key = match key_str {
|
2017-02-13 16:38:47 +01:00
|
|
|
Some(ref k) if k.starts_with("0x") => Bytes::from_str(k).map_err(V::Error::custom)?,
|
2016-07-05 15:16:27 +02:00
|
|
|
Some(k) => Bytes::new(k.into_bytes()),
|
|
|
|
None => { break; }
|
|
|
|
};
|
|
|
|
|
2017-07-06 11:36:15 +02:00
|
|
|
let val_str: Option<String> = visitor.next_value()?;
|
2016-07-05 15:16:27 +02:00
|
|
|
let val = match val_str {
|
2017-02-13 16:38:47 +01:00
|
|
|
Some(ref v) if v.starts_with("0x") => Some(Bytes::from_str(v).map_err(V::Error::custom)?),
|
2016-07-05 15:16:27 +02:00
|
|
|
Some(v) => Some(Bytes::new(v.into_bytes())),
|
|
|
|
None => None,
|
|
|
|
};
|
|
|
|
|
|
|
|
result.insert(key, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
let input = Input {
|
|
|
|
data: result
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(input)
|
|
|
|
}
|
|
|
|
|
2017-07-06 11:36:15 +02:00
|
|
|
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error> where V: SeqAccess<'a> {
|
2016-07-05 15:16:27 +02:00
|
|
|
let mut result = BTreeMap::new();
|
|
|
|
|
|
|
|
loop {
|
2017-07-06 11:36:15 +02:00
|
|
|
let keyval: Option<Vec<Option<String>>> = visitor.next_element()?;
|
2016-07-05 15:16:27 +02:00
|
|
|
let keyval = match keyval {
|
|
|
|
Some(k) => k,
|
|
|
|
_ => { break; },
|
|
|
|
};
|
|
|
|
|
|
|
|
if keyval.len() != 2 {
|
2017-02-13 16:38:47 +01:00
|
|
|
return Err(V::Error::custom("Invalid key value pair."));
|
2016-07-05 15:16:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
let ref key_str: Option<String> = keyval[0];
|
|
|
|
let ref val_str: Option<String> = keyval[1];
|
|
|
|
|
|
|
|
let key = match *key_str {
|
2017-02-13 16:38:47 +01:00
|
|
|
Some(ref k) if k.starts_with("0x") => Bytes::from_str(k).map_err(V::Error::custom)?,
|
2016-07-05 15:16:27 +02:00
|
|
|
Some(ref k) => Bytes::new(k.clone().into_bytes()),
|
|
|
|
None => { break; }
|
|
|
|
};
|
|
|
|
|
|
|
|
let val = match *val_str {
|
2017-02-13 16:38:47 +01:00
|
|
|
Some(ref v) if v.starts_with("0x") => Some(Bytes::from_str(v).map_err(V::Error::custom)?),
|
2016-07-05 15:16:27 +02:00
|
|
|
Some(ref v) => Some(Bytes::new(v.clone().into_bytes())),
|
|
|
|
None => None,
|
|
|
|
};
|
|
|
|
|
|
|
|
result.insert(key, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
let input = Input {
|
|
|
|
data: result
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(input)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use std::collections::BTreeMap;
|
|
|
|
use serde_json;
|
|
|
|
use bytes::Bytes;
|
|
|
|
use super::Input;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn input_deserialization_from_map() {
|
|
|
|
let s = r#"{
|
|
|
|
"0x0045" : "0x0123456789",
|
|
|
|
"be" : "e",
|
|
|
|
"0x0a" : null
|
|
|
|
}"#;
|
|
|
|
|
|
|
|
let input: Input = serde_json::from_str(s).unwrap();
|
|
|
|
let mut map = BTreeMap::new();
|
|
|
|
map.insert(Bytes::new(vec![0, 0x45]), Some(Bytes::new(vec![0x01, 0x23, 0x45, 0x67, 0x89])));
|
|
|
|
map.insert(Bytes::new(vec![0x62, 0x65]), Some(Bytes::new(vec![0x65])));
|
|
|
|
map.insert(Bytes::new(vec![0x0a]), None);
|
|
|
|
assert_eq!(input.data, map);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn input_deserialization_from_array() {
|
|
|
|
let s = r#"[
|
|
|
|
["0x0045", "0x0123456789"],
|
|
|
|
["be", "e"],
|
|
|
|
["0x0a", null]
|
|
|
|
]"#;
|
|
|
|
|
|
|
|
let input: Input = serde_json::from_str(s).unwrap();
|
|
|
|
let mut map = BTreeMap::new();
|
|
|
|
map.insert(Bytes::new(vec![0, 0x45]), Some(Bytes::new(vec![0x01, 0x23, 0x45, 0x67, 0x89])));
|
|
|
|
map.insert(Bytes::new(vec![0x62, 0x65]), Some(Bytes::new(vec![0x65])));
|
|
|
|
map.insert(Bytes::new(vec![0x0a]), None);
|
|
|
|
assert_eq!(input.data, map);
|
|
|
|
}
|
|
|
|
}
|