Make Decodable
and Decoder
infallible.
`Decoder` has two impls: - opaque: this impl is already partly infallible, i.e. in some places it currently panics on failure (e.g. if the input is too short, or on a bad `Result` discriminant), and in some places it returns an error (e.g. on a bad `Option` discriminant). The number of places where either happens is surprisingly small, just because the binary representation has very little redundancy and a lot of input reading can occur even on malformed data. - json: this impl is fully fallible, but it's only used (a) for the `.rlink` file production, and there's a `FIXME` comment suggesting it should change to a binary format, and (b) in a few tests in non-fundamental ways. Indeed #85993 is open to remove it entirely. And the top-level places in the compiler that call into decoding just abort on error anyway. So the fallibility is providing little value, and getting rid of it leads to some non-trivial performance improvements. Much of this commit is pretty boring and mechanical. Some notes about a few interesting parts: - The commit removes `Decoder::{Error,error}`. - `InternIteratorElement::intern_with`: the impl for `T` now has the same optimization for small counts that the impl for `Result<T, E>` has, because it's now much hotter. - Decodable impls for SmallVec, LinkedList, VecDeque now all use `collect`, which is nice; the one for `Vec` uses unsafe code, because that gave better perf on some benchmarks.
This commit is contained in:
parent
88600a6d7f
commit
416399dc10
39 changed files with 726 additions and 781 deletions
|
@ -17,15 +17,8 @@ impl<S: Encoder, A: Array<Item: Encodable<S>>> Encodable<S> for SmallVec<A> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, A: Array<Item: Decodable<D>>> Decodable<D> for SmallVec<A> {
|
||||
fn decode(d: &mut D) -> Result<SmallVec<A>, D::Error> {
|
||||
d.read_seq(|d, len| {
|
||||
let mut vec = SmallVec::with_capacity(len);
|
||||
// FIXME(#48994) - could just be collected into a Result<SmallVec, D::Error>
|
||||
for _ in 0..len {
|
||||
vec.push(d.read_seq_elt(|d| Decodable::decode(d))?);
|
||||
}
|
||||
Ok(vec)
|
||||
})
|
||||
fn decode(d: &mut D) -> SmallVec<A> {
|
||||
d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,14 +34,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for LinkedList<T> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for LinkedList<T> {
|
||||
fn decode(d: &mut D) -> Result<LinkedList<T>, D::Error> {
|
||||
d.read_seq(|d, len| {
|
||||
let mut list = LinkedList::new();
|
||||
for _ in 0..len {
|
||||
list.push_back(d.read_seq_elt(|d| Decodable::decode(d))?);
|
||||
}
|
||||
Ok(list)
|
||||
})
|
||||
fn decode(d: &mut D) -> LinkedList<T> {
|
||||
d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,14 +51,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for VecDeque<T> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for VecDeque<T> {
|
||||
fn decode(d: &mut D) -> Result<VecDeque<T>, D::Error> {
|
||||
d.read_seq(|d, len| {
|
||||
let mut deque: VecDeque<T> = VecDeque::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
deque.push_back(d.read_seq_elt(|d| Decodable::decode(d))?);
|
||||
}
|
||||
Ok(deque)
|
||||
})
|
||||
fn decode(d: &mut D) -> VecDeque<T> {
|
||||
d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,15 +77,15 @@ where
|
|||
K: Decodable<D> + PartialEq + Ord,
|
||||
V: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Result<BTreeMap<K, V>, D::Error> {
|
||||
fn decode(d: &mut D) -> BTreeMap<K, V> {
|
||||
d.read_map(|d, len| {
|
||||
let mut map = BTreeMap::new();
|
||||
for _ in 0..len {
|
||||
let key = d.read_map_elt_key(|d| Decodable::decode(d))?;
|
||||
let val = d.read_map_elt_val(|d| Decodable::decode(d))?;
|
||||
let key = d.read_map_elt_key(|d| Decodable::decode(d));
|
||||
let val = d.read_map_elt_val(|d| Decodable::decode(d));
|
||||
map.insert(key, val);
|
||||
}
|
||||
Ok(map)
|
||||
map
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -127,13 +108,13 @@ impl<D: Decoder, T> Decodable<D> for BTreeSet<T>
|
|||
where
|
||||
T: Decodable<D> + PartialEq + Ord,
|
||||
{
|
||||
fn decode(d: &mut D) -> Result<BTreeSet<T>, D::Error> {
|
||||
fn decode(d: &mut D) -> BTreeSet<T> {
|
||||
d.read_seq(|d, len| {
|
||||
let mut set = BTreeSet::new();
|
||||
for _ in 0..len {
|
||||
set.insert(d.read_seq_elt(|d| Decodable::decode(d))?);
|
||||
set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
|
||||
}
|
||||
Ok(set)
|
||||
set
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -161,16 +142,16 @@ where
|
|||
V: Decodable<D>,
|
||||
S: BuildHasher + Default,
|
||||
{
|
||||
fn decode(d: &mut D) -> Result<HashMap<K, V, S>, D::Error> {
|
||||
fn decode(d: &mut D) -> HashMap<K, V, S> {
|
||||
d.read_map(|d, len| {
|
||||
let state = Default::default();
|
||||
let mut map = HashMap::with_capacity_and_hasher(len, state);
|
||||
for _ in 0..len {
|
||||
let key = d.read_map_elt_key(|d| Decodable::decode(d))?;
|
||||
let val = d.read_map_elt_val(|d| Decodable::decode(d))?;
|
||||
let key = d.read_map_elt_key(|d| Decodable::decode(d));
|
||||
let val = d.read_map_elt_val(|d| Decodable::decode(d));
|
||||
map.insert(key, val);
|
||||
}
|
||||
Ok(map)
|
||||
map
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -205,14 +186,14 @@ where
|
|||
T: Decodable<D> + Hash + Eq,
|
||||
S: BuildHasher + Default,
|
||||
{
|
||||
fn decode(d: &mut D) -> Result<HashSet<T, S>, D::Error> {
|
||||
fn decode(d: &mut D) -> HashSet<T, S> {
|
||||
d.read_seq(|d, len| {
|
||||
let state = Default::default();
|
||||
let mut set = HashSet::with_capacity_and_hasher(len, state);
|
||||
for _ in 0..len {
|
||||
set.insert(d.read_seq_elt(|d| Decodable::decode(d))?);
|
||||
set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
|
||||
}
|
||||
Ok(set)
|
||||
set
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -240,16 +221,16 @@ where
|
|||
V: Decodable<D>,
|
||||
S: BuildHasher + Default,
|
||||
{
|
||||
fn decode(d: &mut D) -> Result<indexmap::IndexMap<K, V, S>, D::Error> {
|
||||
fn decode(d: &mut D) -> indexmap::IndexMap<K, V, S> {
|
||||
d.read_map(|d, len| {
|
||||
let state = Default::default();
|
||||
let mut map = indexmap::IndexMap::with_capacity_and_hasher(len, state);
|
||||
for _ in 0..len {
|
||||
let key = d.read_map_elt_key(|d| Decodable::decode(d))?;
|
||||
let val = d.read_map_elt_val(|d| Decodable::decode(d))?;
|
||||
let key = d.read_map_elt_key(|d| Decodable::decode(d));
|
||||
let val = d.read_map_elt_val(|d| Decodable::decode(d));
|
||||
map.insert(key, val);
|
||||
}
|
||||
Ok(map)
|
||||
map
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -274,14 +255,14 @@ where
|
|||
T: Decodable<D> + Hash + Eq,
|
||||
S: BuildHasher + Default,
|
||||
{
|
||||
fn decode(d: &mut D) -> Result<indexmap::IndexSet<T, S>, D::Error> {
|
||||
fn decode(d: &mut D) -> indexmap::IndexSet<T, S> {
|
||||
d.read_seq(|d, len| {
|
||||
let state = Default::default();
|
||||
let mut set = indexmap::IndexSet::with_capacity_and_hasher(len, state);
|
||||
for _ in 0..len {
|
||||
set.insert(d.read_seq_elt(|d| Decodable::decode(d))?);
|
||||
set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
|
||||
}
|
||||
Ok(set)
|
||||
set
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -294,9 +275,9 @@ impl<E: Encoder, T: Encodable<E>> Encodable<E> for Rc<[T]> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<[T]> {
|
||||
fn decode(d: &mut D) -> Result<Rc<[T]>, D::Error> {
|
||||
let vec: Vec<T> = Decodable::decode(d)?;
|
||||
Ok(vec.into())
|
||||
fn decode(d: &mut D) -> Rc<[T]> {
|
||||
let vec: Vec<T> = Decodable::decode(d);
|
||||
vec.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,8 +289,8 @@ impl<E: Encoder, T: Encodable<E>> Encodable<E> for Arc<[T]> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<[T]> {
|
||||
fn decode(d: &mut D) -> Result<Arc<[T]>, D::Error> {
|
||||
let vec: Vec<T> = Decodable::decode(d)?;
|
||||
Ok(vec.into())
|
||||
fn decode(d: &mut D) -> Arc<[T]> {
|
||||
let vec: Vec<T> = Decodable::decode(d);
|
||||
vec.into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
//! let encoded = json::encode(&object).unwrap();
|
||||
//!
|
||||
//! // Deserialize using `json::decode`
|
||||
//! let decoded: TestStruct = json::decode(&encoded[..]).unwrap();
|
||||
//! let decoded: TestStruct = json::decode(&encoded[..]);
|
||||
//! ```
|
||||
//!
|
||||
//! ## Using the `ToJson` trait
|
||||
|
@ -173,7 +173,7 @@
|
|||
//! let json_str: String = json_obj.to_string();
|
||||
//!
|
||||
//! // Deserialize like before
|
||||
//! let decoded: TestStruct = json::decode(&json_str).unwrap();
|
||||
//! let decoded: TestStruct = json::decode(&json_str);
|
||||
//! ```
|
||||
|
||||
use self::DecoderError::*;
|
||||
|
@ -265,6 +265,12 @@ pub enum DecoderError {
|
|||
ApplicationError(string::String),
|
||||
}
|
||||
|
||||
macro_rules! bad {
|
||||
($e:expr) => {{
|
||||
panic!("json decode error: {:?}", $e);
|
||||
}};
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum EncoderError {
|
||||
FmtError(fmt::Error),
|
||||
|
@ -295,10 +301,10 @@ pub fn error_str(error: ErrorCode) -> &'static str {
|
|||
}
|
||||
|
||||
/// Shortcut function to decode a JSON `&str` into an object
|
||||
pub fn decode<T: crate::Decodable<Decoder>>(s: &str) -> DecodeResult<T> {
|
||||
pub fn decode<T: crate::Decodable<Decoder>>(s: &str) -> T {
|
||||
let json = match from_str(s) {
|
||||
Ok(x) => x,
|
||||
Err(e) => return Err(ParseError(e)),
|
||||
Err(e) => bad!(ParseError(e)),
|
||||
};
|
||||
|
||||
let mut decoder = Decoder::new(json);
|
||||
|
@ -334,15 +340,6 @@ impl fmt::Display for ParserError {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DecoderError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// FIXME this should be a nicer error
|
||||
fmt::Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for DecoderError {}
|
||||
|
||||
impl fmt::Display for EncoderError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
// FIXME this should be a nicer error
|
||||
|
@ -2206,41 +2203,39 @@ impl Decoder {
|
|||
macro_rules! expect {
|
||||
($e:expr, Null) => {{
|
||||
match $e {
|
||||
Json::Null => Ok(()),
|
||||
other => Err(ExpectedError("Null".to_owned(), other.to_string())),
|
||||
Json::Null => (),
|
||||
other => bad!(ExpectedError("Null".to_owned(), other.to_string())),
|
||||
}
|
||||
}};
|
||||
($e:expr, $t:ident) => {{
|
||||
match $e {
|
||||
Json::$t(v) => Ok(v),
|
||||
other => Err(ExpectedError(stringify!($t).to_owned(), other.to_string())),
|
||||
Json::$t(v) => v,
|
||||
other => bad!(ExpectedError(stringify!($t).to_owned(), other.to_string())),
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! read_primitive {
|
||||
($name:ident, $ty:ty) => {
|
||||
fn $name(&mut self) -> DecodeResult<$ty> {
|
||||
fn $name(&mut self) -> $ty {
|
||||
match self.pop() {
|
||||
Json::I64(f) => Ok(f as $ty),
|
||||
Json::U64(f) => Ok(f as $ty),
|
||||
Json::F64(f) => Err(ExpectedError("Integer".to_owned(), f.to_string())),
|
||||
Json::I64(f) => f as $ty,
|
||||
Json::U64(f) => f as $ty,
|
||||
Json::F64(f) => bad!(ExpectedError("Integer".to_owned(), f.to_string())),
|
||||
// re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
|
||||
// is going to have a string here, as per JSON spec.
|
||||
Json::String(s) => match s.parse().ok() {
|
||||
Some(f) => Ok(f),
|
||||
None => Err(ExpectedError("Number".to_owned(), s)),
|
||||
Some(f) => f,
|
||||
None => bad!(ExpectedError("Number".to_owned(), s)),
|
||||
},
|
||||
value => Err(ExpectedError("Number".to_owned(), value.to_string())),
|
||||
value => bad!(ExpectedError("Number".to_owned(), value.to_string())),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl crate::Decoder for Decoder {
|
||||
type Error = DecoderError;
|
||||
|
||||
fn read_unit(&mut self) -> DecodeResult<()> {
|
||||
fn read_unit(&mut self) -> () {
|
||||
expect!(self.pop(), Null)
|
||||
}
|
||||
|
||||
|
@ -2257,156 +2252,151 @@ impl crate::Decoder for Decoder {
|
|||
read_primitive! { read_i64, i64 }
|
||||
read_primitive! { read_i128, i128 }
|
||||
|
||||
fn read_f32(&mut self) -> DecodeResult<f32> {
|
||||
self.read_f64().map(|x| x as f32)
|
||||
fn read_f32(&mut self) -> f32 {
|
||||
self.read_f64() as f32
|
||||
}
|
||||
|
||||
fn read_f64(&mut self) -> DecodeResult<f64> {
|
||||
fn read_f64(&mut self) -> f64 {
|
||||
match self.pop() {
|
||||
Json::I64(f) => Ok(f as f64),
|
||||
Json::U64(f) => Ok(f as f64),
|
||||
Json::F64(f) => Ok(f),
|
||||
Json::I64(f) => f as f64,
|
||||
Json::U64(f) => f as f64,
|
||||
Json::F64(f) => f,
|
||||
Json::String(s) => {
|
||||
// re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
|
||||
// is going to have a string here, as per JSON spec.
|
||||
match s.parse().ok() {
|
||||
Some(f) => Ok(f),
|
||||
None => Err(ExpectedError("Number".to_owned(), s)),
|
||||
Some(f) => f,
|
||||
None => bad!(ExpectedError("Number".to_owned(), s)),
|
||||
}
|
||||
}
|
||||
Json::Null => Ok(f64::NAN),
|
||||
value => Err(ExpectedError("Number".to_owned(), value.to_string())),
|
||||
Json::Null => f64::NAN,
|
||||
value => bad!(ExpectedError("Number".to_owned(), value.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
fn read_bool(&mut self) -> DecodeResult<bool> {
|
||||
fn read_bool(&mut self) -> bool {
|
||||
expect!(self.pop(), Boolean)
|
||||
}
|
||||
|
||||
fn read_char(&mut self) -> DecodeResult<char> {
|
||||
let s = self.read_str()?;
|
||||
{
|
||||
let mut it = s.chars();
|
||||
if let (Some(c), None) = (it.next(), it.next()) {
|
||||
// exactly one character
|
||||
return Ok(c);
|
||||
}
|
||||
fn read_char(&mut self) -> char {
|
||||
let s = self.read_str();
|
||||
let mut it = s.chars();
|
||||
if let (Some(c), None) = (it.next(), it.next()) {
|
||||
// exactly one character
|
||||
return c;
|
||||
}
|
||||
Err(ExpectedError("single character string".to_owned(), s.to_string()))
|
||||
bad!(ExpectedError("single character string".to_owned(), s.to_string()));
|
||||
}
|
||||
|
||||
fn read_str(&mut self) -> DecodeResult<Cow<'_, str>> {
|
||||
expect!(self.pop(), String).map(Cow::Owned)
|
||||
fn read_str(&mut self) -> Cow<'_, str> {
|
||||
Cow::Owned(expect!(self.pop(), String))
|
||||
}
|
||||
|
||||
fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), Self::Error> {
|
||||
fn read_raw_bytes_into(&mut self, s: &mut [u8]) {
|
||||
for c in s.iter_mut() {
|
||||
*c = self.read_u8()?;
|
||||
*c = self.read_u8();
|
||||
}
|
||||
Ok(())
|
||||
()
|
||||
}
|
||||
|
||||
fn read_enum<T, F>(&mut self, f: F) -> DecodeResult<T>
|
||||
fn read_enum<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F) -> DecodeResult<T>
|
||||
fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F) -> T
|
||||
where
|
||||
F: FnMut(&mut Decoder, usize) -> DecodeResult<T>,
|
||||
F: FnMut(&mut Decoder, usize) -> T,
|
||||
{
|
||||
let name = match self.pop() {
|
||||
Json::String(s) => s,
|
||||
Json::Object(mut o) => {
|
||||
let n = match o.remove("variant") {
|
||||
Some(Json::String(s)) => s,
|
||||
Some(val) => return Err(ExpectedError("String".to_owned(), val.to_string())),
|
||||
None => return Err(MissingFieldError("variant".to_owned())),
|
||||
Some(val) => bad!(ExpectedError("String".to_owned(), val.to_string())),
|
||||
None => bad!(MissingFieldError("variant".to_owned())),
|
||||
};
|
||||
match o.remove("fields") {
|
||||
Some(Json::Array(l)) => {
|
||||
self.stack.extend(l.into_iter().rev());
|
||||
}
|
||||
Some(val) => return Err(ExpectedError("Array".to_owned(), val.to_string())),
|
||||
None => return Err(MissingFieldError("fields".to_owned())),
|
||||
Some(val) => bad!(ExpectedError("Array".to_owned(), val.to_string())),
|
||||
None => bad!(MissingFieldError("fields".to_owned())),
|
||||
}
|
||||
n
|
||||
}
|
||||
json => return Err(ExpectedError("String or Object".to_owned(), json.to_string())),
|
||||
json => bad!(ExpectedError("String or Object".to_owned(), json.to_string())),
|
||||
};
|
||||
let idx = match names.iter().position(|n| *n == &name[..]) {
|
||||
Some(idx) => idx,
|
||||
None => return Err(UnknownVariantError(name)),
|
||||
None => bad!(UnknownVariantError(name)),
|
||||
};
|
||||
f(self, idx)
|
||||
}
|
||||
|
||||
fn read_enum_variant_arg<T, F>(&mut self, f: F) -> DecodeResult<T>
|
||||
fn read_enum_variant_arg<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_struct<T, F>(&mut self, f: F) -> DecodeResult<T>
|
||||
fn read_struct<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder) -> T,
|
||||
{
|
||||
let value = f(self)?;
|
||||
let value = f(self);
|
||||
self.pop();
|
||||
Ok(value)
|
||||
value
|
||||
}
|
||||
|
||||
fn read_struct_field<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T>
|
||||
fn read_struct_field<T, F>(&mut self, name: &str, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder) -> T,
|
||||
{
|
||||
let mut obj = expect!(self.pop(), Object)?;
|
||||
let mut obj = expect!(self.pop(), Object);
|
||||
|
||||
let value = match obj.remove(name) {
|
||||
None => {
|
||||
// Add a Null and try to parse it as an Option<_>
|
||||
// to get None as a default value.
|
||||
self.stack.push(Json::Null);
|
||||
match f(self) {
|
||||
Ok(x) => x,
|
||||
Err(_) => return Err(MissingFieldError(name.to_string())),
|
||||
}
|
||||
f(self)
|
||||
}
|
||||
Some(json) => {
|
||||
self.stack.push(json);
|
||||
f(self)?
|
||||
f(self)
|
||||
}
|
||||
};
|
||||
self.stack.push(Json::Object(obj));
|
||||
Ok(value)
|
||||
value
|
||||
}
|
||||
|
||||
fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> DecodeResult<T>
|
||||
fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder) -> T,
|
||||
{
|
||||
self.read_seq(move |d, len| {
|
||||
if len == tuple_len {
|
||||
f(d)
|
||||
} else {
|
||||
Err(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len)))
|
||||
bad!(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len)));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn read_tuple_arg<T, F>(&mut self, f: F) -> DecodeResult<T>
|
||||
fn read_tuple_arg<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder) -> T,
|
||||
{
|
||||
self.read_seq_elt(f)
|
||||
}
|
||||
|
||||
fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T>
|
||||
fn read_option<T, F>(&mut self, mut f: F) -> T
|
||||
where
|
||||
F: FnMut(&mut Decoder, bool) -> DecodeResult<T>,
|
||||
F: FnMut(&mut Decoder, bool) -> T,
|
||||
{
|
||||
match self.pop() {
|
||||
Json::Null => f(self, false),
|
||||
|
@ -2417,28 +2407,28 @@ impl crate::Decoder for Decoder {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T>
|
||||
fn read_seq<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder, usize) -> T,
|
||||
{
|
||||
let array = expect!(self.pop(), Array)?;
|
||||
let array = expect!(self.pop(), Array);
|
||||
let len = array.len();
|
||||
self.stack.extend(array.into_iter().rev());
|
||||
f(self, len)
|
||||
}
|
||||
|
||||
fn read_seq_elt<T, F>(&mut self, f: F) -> DecodeResult<T>
|
||||
fn read_seq_elt<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T>
|
||||
fn read_map<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder, usize) -> T,
|
||||
{
|
||||
let obj = expect!(self.pop(), Object)?;
|
||||
let obj = expect!(self.pop(), Object);
|
||||
let len = obj.len();
|
||||
for (key, value) in obj {
|
||||
self.stack.push(value);
|
||||
|
@ -2447,23 +2437,19 @@ impl crate::Decoder for Decoder {
|
|||
f(self, len)
|
||||
}
|
||||
|
||||
fn read_map_elt_key<T, F>(&mut self, f: F) -> DecodeResult<T>
|
||||
fn read_map_elt_key<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_map_elt_val<T, F>(&mut self, f: F) -> DecodeResult<T>
|
||||
fn read_map_elt_val<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
|
||||
F: FnOnce(&mut Decoder) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn error(&mut self, err: &str) -> DecoderError {
|
||||
ApplicationError(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for converting values to JSON
|
||||
|
|
|
@ -560,134 +560,127 @@ impl<'a> Decoder<'a> {
|
|||
}
|
||||
|
||||
macro_rules! read_leb128 {
|
||||
($dec:expr, $fun:ident) => {{ Ok(leb128::$fun($dec.data, &mut $dec.position)) }};
|
||||
($dec:expr, $fun:ident) => {{ leb128::$fun($dec.data, &mut $dec.position) }};
|
||||
}
|
||||
|
||||
impl<'a> serialize::Decoder for Decoder<'a> {
|
||||
type Error = String;
|
||||
|
||||
#[inline]
|
||||
fn read_unit(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(())
|
||||
fn read_unit(&mut self) -> () {
|
||||
()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u128(&mut self) -> Result<u128, Self::Error> {
|
||||
fn read_u128(&mut self) -> u128 {
|
||||
read_leb128!(self, read_u128_leb128)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u64(&mut self) -> Result<u64, Self::Error> {
|
||||
fn read_u64(&mut self) -> u64 {
|
||||
read_leb128!(self, read_u64_leb128)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u32(&mut self) -> Result<u32, Self::Error> {
|
||||
fn read_u32(&mut self) -> u32 {
|
||||
read_leb128!(self, read_u32_leb128)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u16(&mut self) -> Result<u16, Self::Error> {
|
||||
fn read_u16(&mut self) -> u16 {
|
||||
let bytes = [self.data[self.position], self.data[self.position + 1]];
|
||||
let value = u16::from_le_bytes(bytes);
|
||||
self.position += 2;
|
||||
Ok(value)
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_u8(&mut self) -> Result<u8, Self::Error> {
|
||||
fn read_u8(&mut self) -> u8 {
|
||||
let value = self.data[self.position];
|
||||
self.position += 1;
|
||||
Ok(value)
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_usize(&mut self) -> Result<usize, Self::Error> {
|
||||
fn read_usize(&mut self) -> usize {
|
||||
read_leb128!(self, read_usize_leb128)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_i128(&mut self) -> Result<i128, Self::Error> {
|
||||
fn read_i128(&mut self) -> i128 {
|
||||
read_leb128!(self, read_i128_leb128)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_i64(&mut self) -> Result<i64, Self::Error> {
|
||||
fn read_i64(&mut self) -> i64 {
|
||||
read_leb128!(self, read_i64_leb128)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_i32(&mut self) -> Result<i32, Self::Error> {
|
||||
fn read_i32(&mut self) -> i32 {
|
||||
read_leb128!(self, read_i32_leb128)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_i16(&mut self) -> Result<i16, Self::Error> {
|
||||
fn read_i16(&mut self) -> i16 {
|
||||
let bytes = [self.data[self.position], self.data[self.position + 1]];
|
||||
let value = i16::from_le_bytes(bytes);
|
||||
self.position += 2;
|
||||
Ok(value)
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_i8(&mut self) -> Result<i8, Self::Error> {
|
||||
fn read_i8(&mut self) -> i8 {
|
||||
let as_u8 = self.data[self.position];
|
||||
self.position += 1;
|
||||
unsafe { Ok(::std::mem::transmute(as_u8)) }
|
||||
unsafe { ::std::mem::transmute(as_u8) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_isize(&mut self) -> Result<isize, Self::Error> {
|
||||
fn read_isize(&mut self) -> isize {
|
||||
read_leb128!(self, read_isize_leb128)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_bool(&mut self) -> Result<bool, Self::Error> {
|
||||
let value = self.read_u8()?;
|
||||
Ok(value != 0)
|
||||
fn read_bool(&mut self) -> bool {
|
||||
let value = self.read_u8();
|
||||
value != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_f64(&mut self) -> Result<f64, Self::Error> {
|
||||
let bits = self.read_u64()?;
|
||||
Ok(f64::from_bits(bits))
|
||||
fn read_f64(&mut self) -> f64 {
|
||||
let bits = self.read_u64();
|
||||
f64::from_bits(bits)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_f32(&mut self) -> Result<f32, Self::Error> {
|
||||
let bits = self.read_u32()?;
|
||||
Ok(f32::from_bits(bits))
|
||||
fn read_f32(&mut self) -> f32 {
|
||||
let bits = self.read_u32();
|
||||
f32::from_bits(bits)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_char(&mut self) -> Result<char, Self::Error> {
|
||||
let bits = self.read_u32()?;
|
||||
Ok(std::char::from_u32(bits).unwrap())
|
||||
fn read_char(&mut self) -> char {
|
||||
let bits = self.read_u32();
|
||||
std::char::from_u32(bits).unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error> {
|
||||
let len = self.read_usize()?;
|
||||
fn read_str(&mut self) -> Cow<'_, str> {
|
||||
let len = self.read_usize();
|
||||
let sentinel = self.data[self.position + len];
|
||||
assert!(sentinel == STR_SENTINEL);
|
||||
let s = unsafe {
|
||||
std::str::from_utf8_unchecked(&self.data[self.position..self.position + len])
|
||||
};
|
||||
self.position += len + 1;
|
||||
Ok(Cow::Borrowed(s))
|
||||
Cow::Borrowed(s)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn error(&mut self, err: &str) -> Self::Error {
|
||||
err.to_string()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), String> {
|
||||
fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> () {
|
||||
let start = self.position;
|
||||
self.position += s.len();
|
||||
s.copy_from_slice(&self.data[start..self.position]);
|
||||
Ok(())
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -715,9 +708,9 @@ impl serialize::Encodable<FileEncoder> for [u8] {
|
|||
// Specialize decoding `Vec<u8>`. This specialization also applies to decoding `Box<[u8]>`s, etc.,
|
||||
// since the default implementations call `decode` to produce a `Vec<u8>` internally.
|
||||
impl<'a> serialize::Decodable<Decoder<'a>> for Vec<u8> {
|
||||
fn decode(d: &mut Decoder<'a>) -> Result<Self, String> {
|
||||
let len = serialize::Decoder::read_usize(d)?;
|
||||
Ok(d.read_raw_bytes(len).to_owned())
|
||||
fn decode(d: &mut Decoder<'a>) -> Self {
|
||||
let len = serialize::Decoder::read_usize(d);
|
||||
d.read_raw_bytes(len).to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -752,13 +745,13 @@ impl serialize::Encodable<FileEncoder> for IntEncodedWithFixedSize {
|
|||
|
||||
impl<'a> serialize::Decodable<Decoder<'a>> for IntEncodedWithFixedSize {
|
||||
#[inline]
|
||||
fn decode(decoder: &mut Decoder<'a>) -> Result<IntEncodedWithFixedSize, String> {
|
||||
fn decode(decoder: &mut Decoder<'a>) -> IntEncodedWithFixedSize {
|
||||
let _start_pos = decoder.position();
|
||||
let bytes = decoder.read_raw_bytes(IntEncodedWithFixedSize::ENCODED_SIZE);
|
||||
let _end_pos = decoder.position();
|
||||
debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
|
||||
|
||||
let value = u64::from_le_bytes(bytes.try_into().unwrap());
|
||||
Ok(IntEncodedWithFixedSize(value))
|
||||
IntEncodedWithFixedSize(value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -173,144 +173,145 @@ pub trait Encoder {
|
|||
}
|
||||
}
|
||||
|
||||
// Note: all the methods in this trait are infallible, which may be surprising.
|
||||
// They used to be fallible (i.e. return a `Result`) but many of the impls just
|
||||
// panicked when something went wrong, and for the cases that didn't the
|
||||
// top-level invocation would also just panic on failure. Switching to
|
||||
// infallibility made things faster and lots of code a little simpler and more
|
||||
// concise.
|
||||
pub trait Decoder {
|
||||
type Error;
|
||||
|
||||
// Primitive types:
|
||||
fn read_unit(&mut self) -> Result<(), Self::Error>;
|
||||
fn read_usize(&mut self) -> Result<usize, Self::Error>;
|
||||
fn read_u128(&mut self) -> Result<u128, Self::Error>;
|
||||
fn read_u64(&mut self) -> Result<u64, Self::Error>;
|
||||
fn read_u32(&mut self) -> Result<u32, Self::Error>;
|
||||
fn read_u16(&mut self) -> Result<u16, Self::Error>;
|
||||
fn read_u8(&mut self) -> Result<u8, Self::Error>;
|
||||
fn read_isize(&mut self) -> Result<isize, Self::Error>;
|
||||
fn read_i128(&mut self) -> Result<i128, Self::Error>;
|
||||
fn read_i64(&mut self) -> Result<i64, Self::Error>;
|
||||
fn read_i32(&mut self) -> Result<i32, Self::Error>;
|
||||
fn read_i16(&mut self) -> Result<i16, Self::Error>;
|
||||
fn read_i8(&mut self) -> Result<i8, Self::Error>;
|
||||
fn read_bool(&mut self) -> Result<bool, Self::Error>;
|
||||
fn read_f64(&mut self) -> Result<f64, Self::Error>;
|
||||
fn read_f32(&mut self) -> Result<f32, Self::Error>;
|
||||
fn read_char(&mut self) -> Result<char, Self::Error>;
|
||||
fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error>;
|
||||
fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), Self::Error>;
|
||||
fn read_unit(&mut self) -> ();
|
||||
fn read_usize(&mut self) -> usize;
|
||||
fn read_u128(&mut self) -> u128;
|
||||
fn read_u64(&mut self) -> u64;
|
||||
fn read_u32(&mut self) -> u32;
|
||||
fn read_u16(&mut self) -> u16;
|
||||
fn read_u8(&mut self) -> u8;
|
||||
fn read_isize(&mut self) -> isize;
|
||||
fn read_i128(&mut self) -> i128;
|
||||
fn read_i64(&mut self) -> i64;
|
||||
fn read_i32(&mut self) -> i32;
|
||||
fn read_i16(&mut self) -> i16;
|
||||
fn read_i8(&mut self) -> i8;
|
||||
fn read_bool(&mut self) -> bool;
|
||||
fn read_f64(&mut self) -> f64;
|
||||
fn read_f32(&mut self) -> f32;
|
||||
fn read_char(&mut self) -> char;
|
||||
fn read_str(&mut self) -> Cow<'_, str>;
|
||||
fn read_raw_bytes_into(&mut self, s: &mut [u8]);
|
||||
|
||||
// Compound types:
|
||||
#[inline]
|
||||
fn read_enum<T, F>(&mut self, f: F) -> Result<T, Self::Error>
|
||||
fn read_enum<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_enum_variant<T, F>(&mut self, _names: &[&str], mut f: F) -> Result<T, Self::Error>
|
||||
fn read_enum_variant<T, F>(&mut self, _names: &[&str], mut f: F) -> T
|
||||
where
|
||||
F: FnMut(&mut Self, usize) -> Result<T, Self::Error>,
|
||||
F: FnMut(&mut Self, usize) -> T,
|
||||
{
|
||||
let disr = self.read_usize()?;
|
||||
let disr = self.read_usize();
|
||||
f(self, disr)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_enum_variant_arg<T, F>(&mut self, f: F) -> Result<T, Self::Error>
|
||||
fn read_enum_variant_arg<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_struct<T, F>(&mut self, f: F) -> Result<T, Self::Error>
|
||||
fn read_struct<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_struct_field<T, F>(&mut self, _f_name: &str, f: F) -> Result<T, Self::Error>
|
||||
fn read_struct_field<T, F>(&mut self, _f_name: &str, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_tuple<T, F>(&mut self, _len: usize, f: F) -> Result<T, Self::Error>
|
||||
fn read_tuple<T, F>(&mut self, _len: usize, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_tuple_arg<T, F>(&mut self, f: F) -> Result<T, Self::Error>
|
||||
fn read_tuple_arg<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
// Specialized types:
|
||||
fn read_option<T, F>(&mut self, mut f: F) -> Result<T, Self::Error>
|
||||
fn read_option<T, F>(&mut self, mut f: F) -> T
|
||||
where
|
||||
F: FnMut(&mut Self, bool) -> Result<T, Self::Error>,
|
||||
F: FnMut(&mut Self, bool) -> T,
|
||||
{
|
||||
self.read_enum(move |this| {
|
||||
this.read_enum_variant(&["None", "Some"], move |this, idx| match idx {
|
||||
0 => f(this, false),
|
||||
1 => f(this, true),
|
||||
_ => Err(this.error("read_option: expected 0 for None or 1 for Some")),
|
||||
_ => panic!("read_option: expected 0 for None or 1 for Some"),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn read_seq<T, F>(&mut self, f: F) -> Result<T, Self::Error>
|
||||
fn read_seq<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self, usize) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self, usize) -> T,
|
||||
{
|
||||
let len = self.read_usize()?;
|
||||
let len = self.read_usize();
|
||||
f(self, len)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_seq_elt<T, F>(&mut self, f: F) -> Result<T, Self::Error>
|
||||
fn read_seq_elt<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn read_map<T, F>(&mut self, f: F) -> Result<T, Self::Error>
|
||||
fn read_map<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self, usize) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self, usize) -> T,
|
||||
{
|
||||
let len = self.read_usize()?;
|
||||
let len = self.read_usize();
|
||||
f(self, len)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_map_elt_key<T, F>(&mut self, f: F) -> Result<T, Self::Error>
|
||||
fn read_map_elt_key<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_map_elt_val<T, F>(&mut self, f: F) -> Result<T, Self::Error>
|
||||
fn read_map_elt_val<T, F>(&mut self, f: F) -> T
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
|
||||
F: FnOnce(&mut Self) -> T,
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
// Failure
|
||||
fn error(&mut self, err: &str) -> Self::Error;
|
||||
}
|
||||
|
||||
/// Trait for types that can be serialized
|
||||
|
@ -340,7 +341,7 @@ pub trait Encodable<S: Encoder> {
|
|||
/// * `TyDecodable` should be used for types that are only serialized in crate
|
||||
/// metadata or the incremental cache. This is most types in `rustc_middle`.
|
||||
pub trait Decodable<D: Decoder>: Sized {
|
||||
fn decode(d: &mut D) -> Result<Self, D::Error>;
|
||||
fn decode(d: &mut D) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! direct_serialize_impls {
|
||||
|
@ -353,7 +354,7 @@ macro_rules! direct_serialize_impls {
|
|||
}
|
||||
|
||||
impl<D: Decoder> Decodable<D> for $ty {
|
||||
fn decode(d: &mut D) -> Result<$ty, D::Error> {
|
||||
fn decode(d: &mut D) -> $ty {
|
||||
d.$read_method()
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +388,7 @@ impl<S: Encoder> Encodable<S> for ! {
|
|||
}
|
||||
|
||||
impl<D: Decoder> Decodable<D> for ! {
|
||||
fn decode(_d: &mut D) -> Result<!, D::Error> {
|
||||
fn decode(_d: &mut D) -> ! {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
@ -399,8 +400,8 @@ impl<S: Encoder> Encodable<S> for ::std::num::NonZeroU32 {
|
|||
}
|
||||
|
||||
impl<D: Decoder> Decodable<D> for ::std::num::NonZeroU32 {
|
||||
fn decode(d: &mut D) -> Result<Self, D::Error> {
|
||||
d.read_u32().map(|d| ::std::num::NonZeroU32::new(d).unwrap())
|
||||
fn decode(d: &mut D) -> Self {
|
||||
::std::num::NonZeroU32::new(d.read_u32()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,8 +424,8 @@ impl<S: Encoder> Encodable<S> for String {
|
|||
}
|
||||
|
||||
impl<D: Decoder> Decodable<D> for String {
|
||||
fn decode(d: &mut D) -> Result<String, D::Error> {
|
||||
Ok(d.read_str()?.into_owned())
|
||||
fn decode(d: &mut D) -> String {
|
||||
d.read_str().into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,7 +436,7 @@ impl<S: Encoder> Encodable<S> for () {
|
|||
}
|
||||
|
||||
impl<D: Decoder> Decodable<D> for () {
|
||||
fn decode(d: &mut D) -> Result<(), D::Error> {
|
||||
fn decode(d: &mut D) -> () {
|
||||
d.read_unit()
|
||||
}
|
||||
}
|
||||
|
@ -447,16 +448,16 @@ impl<S: Encoder, T> Encodable<S> for PhantomData<T> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T> Decodable<D> for PhantomData<T> {
|
||||
fn decode(d: &mut D) -> Result<PhantomData<T>, D::Error> {
|
||||
d.read_unit()?;
|
||||
Ok(PhantomData)
|
||||
fn decode(d: &mut D) -> PhantomData<T> {
|
||||
d.read_unit();
|
||||
PhantomData
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<[T]> {
|
||||
fn decode(d: &mut D) -> Result<Box<[T]>, D::Error> {
|
||||
let v: Vec<T> = Decodable::decode(d)?;
|
||||
Ok(v.into_boxed_slice())
|
||||
fn decode(d: &mut D) -> Box<[T]> {
|
||||
let v: Vec<T> = Decodable::decode(d);
|
||||
v.into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,8 +468,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Rc<T> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<T> {
|
||||
fn decode(d: &mut D) -> Result<Rc<T>, D::Error> {
|
||||
Ok(Rc::new(Decodable::decode(d)?))
|
||||
fn decode(d: &mut D) -> Rc<T> {
|
||||
Rc::new(Decodable::decode(d))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,13 +492,22 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Vec<T> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
|
||||
default fn decode(d: &mut D) -> Result<Vec<T>, D::Error> {
|
||||
default fn decode(d: &mut D) -> Vec<T> {
|
||||
d.read_seq(|d, len| {
|
||||
let mut v = Vec::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
v.push(d.read_seq_elt(|d| Decodable::decode(d))?);
|
||||
// SAFETY: we set the capacity in advance, only write elements, and
|
||||
// only set the length at the end once the writing has succeeded.
|
||||
let mut vec = Vec::with_capacity(len);
|
||||
unsafe {
|
||||
let ptr: *mut T = vec.as_mut_ptr();
|
||||
for i in 0..len {
|
||||
std::ptr::write(
|
||||
ptr.offset(i as isize),
|
||||
d.read_seq_elt(|d| Decodable::decode(d)),
|
||||
);
|
||||
}
|
||||
vec.set_len(len);
|
||||
}
|
||||
Ok(v)
|
||||
vec
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -510,14 +520,14 @@ impl<S: Encoder, T: Encodable<S>, const N: usize> Encodable<S> for [T; N] {
|
|||
}
|
||||
|
||||
impl<D: Decoder, const N: usize> Decodable<D> for [u8; N] {
|
||||
fn decode(d: &mut D) -> Result<[u8; N], D::Error> {
|
||||
fn decode(d: &mut D) -> [u8; N] {
|
||||
d.read_seq(|d, len| {
|
||||
assert!(len == N);
|
||||
let mut v = [0u8; N];
|
||||
for i in 0..len {
|
||||
v[i] = d.read_seq_elt(|d| Decodable::decode(d))?;
|
||||
v[i] = d.read_seq_elt(|d| Decodable::decode(d));
|
||||
}
|
||||
Ok(v)
|
||||
v
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -536,9 +546,9 @@ impl<D: Decoder, T: Decodable<D> + ToOwned> Decodable<D> for Cow<'static, [T]>
|
|||
where
|
||||
[T]: ToOwned<Owned = Vec<T>>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Result<Cow<'static, [T]>, D::Error> {
|
||||
let v: Vec<T> = Decodable::decode(d)?;
|
||||
Ok(Cow::Owned(v))
|
||||
fn decode(d: &mut D) -> Cow<'static, [T]> {
|
||||
let v: Vec<T> = Decodable::decode(d);
|
||||
Cow::Owned(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -552,8 +562,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Option<T> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Option<T> {
|
||||
fn decode(d: &mut D) -> Result<Option<T>, D::Error> {
|
||||
d.read_option(|d, b| if b { Ok(Some(Decodable::decode(d)?)) } else { Ok(None) })
|
||||
fn decode(d: &mut D) -> Option<T> {
|
||||
d.read_option(|d, b| if b { Some(Decodable::decode(d)) } else { None })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -571,17 +581,12 @@ impl<S: Encoder, T1: Encodable<S>, T2: Encodable<S>> Encodable<S> for Result<T1,
|
|||
}
|
||||
|
||||
impl<D: Decoder, T1: Decodable<D>, T2: Decodable<D>> Decodable<D> for Result<T1, T2> {
|
||||
fn decode(d: &mut D) -> Result<Result<T1, T2>, D::Error> {
|
||||
fn decode(d: &mut D) -> Result<T1, T2> {
|
||||
d.read_enum(|d| {
|
||||
d.read_enum_variant(&["Ok", "Err"], |d, disr| match disr {
|
||||
0 => Ok(Ok(d.read_enum_variant_arg(|d| T1::decode(d))?)),
|
||||
1 => Ok(Err(d.read_enum_variant_arg(|d| T2::decode(d))?)),
|
||||
_ => {
|
||||
panic!(
|
||||
"Encountered invalid discriminant while \
|
||||
decoding `Result`."
|
||||
);
|
||||
}
|
||||
0 => Ok(d.read_enum_variant_arg(|d| T1::decode(d))),
|
||||
1 => Err(d.read_enum_variant_arg(|d| T2::decode(d))),
|
||||
_ => panic!("Encountered invalid discriminant while decoding `Result`."),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -609,13 +614,13 @@ macro_rules! tuple {
|
|||
( $($name:ident,)+ ) => (
|
||||
impl<D: Decoder, $($name: Decodable<D>),+> Decodable<D> for ($($name,)+) {
|
||||
#[allow(non_snake_case)]
|
||||
fn decode(d: &mut D) -> Result<($($name,)+), D::Error> {
|
||||
fn decode(d: &mut D) -> ($($name,)+) {
|
||||
let len: usize = count!($($name)+);
|
||||
d.read_tuple(len, |d| {
|
||||
let ret = ($(d.read_tuple_arg(|d| -> Result<$name, D::Error> {
|
||||
let ret = ($(d.read_tuple_arg(|d| -> $name {
|
||||
Decodable::decode(d)
|
||||
})?,)+);
|
||||
Ok(ret)
|
||||
}),)+);
|
||||
ret
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -651,9 +656,9 @@ impl<S: Encoder> Encodable<S> for path::PathBuf {
|
|||
}
|
||||
|
||||
impl<D: Decoder> Decodable<D> for path::PathBuf {
|
||||
fn decode(d: &mut D) -> Result<path::PathBuf, D::Error> {
|
||||
let bytes: String = Decodable::decode(d)?;
|
||||
Ok(path::PathBuf::from(bytes))
|
||||
fn decode(d: &mut D) -> path::PathBuf {
|
||||
let bytes: String = Decodable::decode(d);
|
||||
path::PathBuf::from(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,8 +669,8 @@ impl<S: Encoder, T: Encodable<S> + Copy> Encodable<S> for Cell<T> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D> + Copy> Decodable<D> for Cell<T> {
|
||||
fn decode(d: &mut D) -> Result<Cell<T>, D::Error> {
|
||||
Ok(Cell::new(Decodable::decode(d)?))
|
||||
fn decode(d: &mut D) -> Cell<T> {
|
||||
Cell::new(Decodable::decode(d))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -681,8 +686,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for RefCell<T> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for RefCell<T> {
|
||||
fn decode(d: &mut D) -> Result<RefCell<T>, D::Error> {
|
||||
Ok(RefCell::new(Decodable::decode(d)?))
|
||||
fn decode(d: &mut D) -> RefCell<T> {
|
||||
RefCell::new(Decodable::decode(d))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -693,8 +698,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Arc<T> {
|
|||
}
|
||||
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<T> {
|
||||
fn decode(d: &mut D) -> Result<Arc<T>, D::Error> {
|
||||
Ok(Arc::new(Decodable::decode(d)?))
|
||||
fn decode(d: &mut D) -> Arc<T> {
|
||||
Arc::new(Decodable::decode(d))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -704,7 +709,7 @@ impl<S: Encoder, T: ?Sized + Encodable<S>> Encodable<S> for Box<T> {
|
|||
}
|
||||
}
|
||||
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<T> {
|
||||
fn decode(d: &mut D) -> Result<Box<T>, D::Error> {
|
||||
Ok(Box::new(Decodable::decode(d)?))
|
||||
fn decode(d: &mut D) -> Box<T> {
|
||||
Box::new(Decodable::decode(d))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
#![allow(rustc::internal)]
|
||||
|
||||
use json::DecoderError::*;
|
||||
use json::ErrorCode::*;
|
||||
use json::Json::*;
|
||||
use json::JsonEvent::*;
|
||||
use json::ParserError::*;
|
||||
use json::{
|
||||
from_str, DecodeResult, Decoder, DecoderError, Encoder, EncoderError, Json, JsonEvent, Parser,
|
||||
StackElement,
|
||||
};
|
||||
use json::{from_str, Decoder, Encoder, EncoderError, Json, JsonEvent, Parser, StackElement};
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use rustc_serialize::json;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
|
@ -26,27 +22,27 @@ struct OptionData {
|
|||
#[test]
|
||||
fn test_decode_option_none() {
|
||||
let s = "{}";
|
||||
let obj: OptionData = json::decode(s).unwrap();
|
||||
let obj: OptionData = json::decode(s);
|
||||
assert_eq!(obj, OptionData { opt: None });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_option_some() {
|
||||
let s = "{ \"opt\": 10 }";
|
||||
let obj: OptionData = json::decode(s).unwrap();
|
||||
let obj: OptionData = json::decode(s);
|
||||
assert_eq!(obj, OptionData { opt: Some(10) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_option_malformed() {
|
||||
check_err::<OptionData>(
|
||||
"{ \"opt\": [] }",
|
||||
ExpectedError("Number".to_string(), "[]".to_string()),
|
||||
);
|
||||
check_err::<OptionData>(
|
||||
"{ \"opt\": false }",
|
||||
ExpectedError("Number".to_string(), "false".to_string()),
|
||||
);
|
||||
#[should_panic(expected = r#"ExpectedError("Number", "[]")"#)]
|
||||
fn test_decode_option_malformed1() {
|
||||
check_err::<OptionData>(r#"{ "opt": [] }"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("Number", "false")"#)]
|
||||
fn test_decode_option_malformed2() {
|
||||
check_err::<OptionData>(r#"{ "opt": false }"#);
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Encodable, Decodable, Debug)]
|
||||
|
@ -329,13 +325,13 @@ fn test_read_identifiers() {
|
|||
|
||||
#[test]
|
||||
fn test_decode_identifiers() {
|
||||
let v: () = json::decode("null").unwrap();
|
||||
let v: () = json::decode("null");
|
||||
assert_eq!(v, ());
|
||||
|
||||
let v: bool = json::decode("true").unwrap();
|
||||
let v: bool = json::decode("true");
|
||||
assert_eq!(v, true);
|
||||
|
||||
let v: bool = json::decode("false").unwrap();
|
||||
let v: bool = json::decode("false");
|
||||
assert_eq!(v, false);
|
||||
}
|
||||
|
||||
|
@ -368,42 +364,42 @@ fn test_read_number() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("Integer", "765.25")"#)]
|
||||
fn test_decode_numbers() {
|
||||
let v: f64 = json::decode("3").unwrap();
|
||||
let v: f64 = json::decode("3");
|
||||
assert_eq!(v, 3.0);
|
||||
|
||||
let v: f64 = json::decode("3.1").unwrap();
|
||||
let v: f64 = json::decode("3.1");
|
||||
assert_eq!(v, 3.1);
|
||||
|
||||
let v: f64 = json::decode("-1.2").unwrap();
|
||||
let v: f64 = json::decode("-1.2");
|
||||
assert_eq!(v, -1.2);
|
||||
|
||||
let v: f64 = json::decode("0.4").unwrap();
|
||||
let v: f64 = json::decode("0.4");
|
||||
assert_eq!(v, 0.4);
|
||||
|
||||
let v: f64 = json::decode("0.4e5").unwrap();
|
||||
let v: f64 = json::decode("0.4e5");
|
||||
assert_eq!(v, 0.4e5);
|
||||
|
||||
let v: f64 = json::decode("0.4e15").unwrap();
|
||||
let v: f64 = json::decode("0.4e15");
|
||||
assert_eq!(v, 0.4e15);
|
||||
|
||||
let v: f64 = json::decode("0.4e-01").unwrap();
|
||||
let v: f64 = json::decode("0.4e-01");
|
||||
assert_eq!(v, 0.4e-01);
|
||||
|
||||
let v: u64 = json::decode("0").unwrap();
|
||||
let v: u64 = json::decode("0");
|
||||
assert_eq!(v, 0);
|
||||
|
||||
let v: u64 = json::decode("18446744073709551615").unwrap();
|
||||
let v: u64 = json::decode("18446744073709551615");
|
||||
assert_eq!(v, u64::MAX);
|
||||
|
||||
let v: i64 = json::decode("-9223372036854775808").unwrap();
|
||||
let v: i64 = json::decode("-9223372036854775808");
|
||||
assert_eq!(v, i64::MIN);
|
||||
|
||||
let v: i64 = json::decode("9223372036854775807").unwrap();
|
||||
let v: i64 = json::decode("9223372036854775807");
|
||||
assert_eq!(v, i64::MAX);
|
||||
|
||||
let res: DecodeResult<i64> = json::decode("765.25");
|
||||
assert_eq!(res, Err(ExpectedError("Integer".to_string(), "765.25".to_string())));
|
||||
json::decode::<i64>("765.25");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -438,7 +434,7 @@ fn test_decode_str() {
|
|||
];
|
||||
|
||||
for (i, o) in s {
|
||||
let v: string::String = json::decode(i).unwrap();
|
||||
let v: string::String = json::decode(i);
|
||||
assert_eq!(v, o);
|
||||
}
|
||||
}
|
||||
|
@ -463,39 +459,41 @@ fn test_read_array() {
|
|||
|
||||
#[test]
|
||||
fn test_decode_array() {
|
||||
let v: Vec<()> = json::decode("[]").unwrap();
|
||||
let v: Vec<()> = json::decode("[]");
|
||||
assert_eq!(v, []);
|
||||
|
||||
let v: Vec<()> = json::decode("[null]").unwrap();
|
||||
let v: Vec<()> = json::decode("[null]");
|
||||
assert_eq!(v, [()]);
|
||||
|
||||
let v: Vec<bool> = json::decode("[true]").unwrap();
|
||||
let v: Vec<bool> = json::decode("[true]");
|
||||
assert_eq!(v, [true]);
|
||||
|
||||
let v: Vec<isize> = json::decode("[3, 1]").unwrap();
|
||||
let v: Vec<isize> = json::decode("[3, 1]");
|
||||
assert_eq!(v, [3, 1]);
|
||||
|
||||
let v: Vec<Vec<usize>> = json::decode("[[3], [1, 2]]").unwrap();
|
||||
let v: Vec<Vec<usize>> = json::decode("[[3], [1, 2]]");
|
||||
assert_eq!(v, [vec![3], vec![1, 2]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_tuple() {
|
||||
let t: (usize, usize, usize) = json::decode("[1, 2, 3]").unwrap();
|
||||
let t: (usize, usize, usize) = json::decode("[1, 2, 3]");
|
||||
assert_eq!(t, (1, 2, 3));
|
||||
|
||||
let t: (usize, string::String) = json::decode("[1, \"two\"]").unwrap();
|
||||
let t: (usize, string::String) = json::decode("[1, \"two\"]");
|
||||
assert_eq!(t, (1, "two".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_decode_tuple_malformed_types() {
|
||||
assert!(json::decode::<(usize, string::String)>("[1, 2]").is_err());
|
||||
json::decode::<(usize, string::String)>("[1, 2]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_decode_tuple_malformed_length() {
|
||||
assert!(json::decode::<(usize, usize)>("[1, 2, 3]").is_err());
|
||||
json::decode::<(usize, usize)>("[1, 2, 3]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -562,7 +560,7 @@ fn test_decode_struct() {
|
|||
]
|
||||
}";
|
||||
|
||||
let v: Outer = json::decode(s).unwrap();
|
||||
let v: Outer = json::decode(s);
|
||||
assert_eq!(
|
||||
v,
|
||||
Outer { inner: vec![Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }] }
|
||||
|
@ -577,7 +575,7 @@ struct FloatStruct {
|
|||
#[test]
|
||||
fn test_decode_struct_with_nan() {
|
||||
let s = "{\"f\":null,\"a\":[null,123]}";
|
||||
let obj: FloatStruct = json::decode(s).unwrap();
|
||||
let obj: FloatStruct = json::decode(s);
|
||||
assert!(obj.f.is_nan());
|
||||
assert!(obj.a[0].is_nan());
|
||||
assert_eq!(obj.a[1], 123f64);
|
||||
|
@ -585,20 +583,20 @@ fn test_decode_struct_with_nan() {
|
|||
|
||||
#[test]
|
||||
fn test_decode_option() {
|
||||
let value: Option<string::String> = json::decode("null").unwrap();
|
||||
let value: Option<string::String> = json::decode("null");
|
||||
assert_eq!(value, None);
|
||||
|
||||
let value: Option<string::String> = json::decode("\"jodhpurs\"").unwrap();
|
||||
let value: Option<string::String> = json::decode("\"jodhpurs\"");
|
||||
assert_eq!(value, Some("jodhpurs".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_enum() {
|
||||
let value: Animal = json::decode("\"Dog\"").unwrap();
|
||||
let value: Animal = json::decode("\"Dog\"");
|
||||
assert_eq!(value, Dog);
|
||||
|
||||
let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}";
|
||||
let value: Animal = json::decode(s).unwrap();
|
||||
let value: Animal = json::decode(s);
|
||||
assert_eq!(value, Frog("Henry".to_string(), 349));
|
||||
}
|
||||
|
||||
|
@ -606,7 +604,7 @@ fn test_decode_enum() {
|
|||
fn test_decode_map() {
|
||||
let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
|
||||
\"fields\":[\"Henry\", 349]}}";
|
||||
let mut map: BTreeMap<string::String, Animal> = json::decode(s).unwrap();
|
||||
let mut map: BTreeMap<string::String, Animal> = json::decode(s);
|
||||
|
||||
assert_eq!(map.remove(&"a".to_string()), Some(Dog));
|
||||
assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349)));
|
||||
|
@ -630,59 +628,65 @@ enum DecodeEnum {
|
|||
A(f64),
|
||||
B(string::String),
|
||||
}
|
||||
fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected: DecoderError) {
|
||||
let res: DecodeResult<T> = match from_str(to_parse) {
|
||||
Err(e) => Err(ParseError(e)),
|
||||
Ok(json) => Decodable::decode(&mut Decoder::new(json)),
|
||||
};
|
||||
match res {
|
||||
Ok(_) => panic!("`{:?}` parsed & decoded ok, expecting error `{:?}`", to_parse, expected),
|
||||
Err(ParseError(e)) => panic!("`{:?}` is not valid json: {:?}", to_parse, e),
|
||||
Err(e) => {
|
||||
assert_eq!(e, expected);
|
||||
}
|
||||
}
|
||||
fn check_err<T: Decodable<Decoder>>(to_parse: &str) {
|
||||
let json = from_str(to_parse).unwrap();
|
||||
let _: T = Decodable::decode(&mut Decoder::new(json));
|
||||
}
|
||||
#[test]
|
||||
fn test_decode_errors_struct() {
|
||||
check_err::<DecodeStruct>("[]", ExpectedError("Object".to_string(), "[]".to_string()));
|
||||
check_err::<DecodeStruct>(
|
||||
"{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}",
|
||||
ExpectedError("Number".to_string(), "true".to_string()),
|
||||
);
|
||||
check_err::<DecodeStruct>(
|
||||
"{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}",
|
||||
ExpectedError("Boolean".to_string(), "[]".to_string()),
|
||||
);
|
||||
check_err::<DecodeStruct>(
|
||||
"{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}",
|
||||
ExpectedError("String".to_string(), "{}".to_string()),
|
||||
);
|
||||
check_err::<DecodeStruct>(
|
||||
"{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}",
|
||||
ExpectedError("Array".to_string(), "null".to_string()),
|
||||
);
|
||||
check_err::<DecodeStruct>(
|
||||
"{\"x\": 1, \"y\": true, \"z\": \"\"}",
|
||||
MissingFieldError("w".to_string()),
|
||||
);
|
||||
#[should_panic(expected = r#"ExpectedError("Object", "[]")"#)]
|
||||
fn test_decode_errors_struct1() {
|
||||
check_err::<DecodeStruct>("[]");
|
||||
}
|
||||
#[test]
|
||||
fn test_decode_errors_enum() {
|
||||
check_err::<DecodeEnum>("{}", MissingFieldError("variant".to_string()));
|
||||
check_err::<DecodeEnum>(
|
||||
"{\"variant\": 1}",
|
||||
ExpectedError("String".to_string(), "1".to_string()),
|
||||
);
|
||||
check_err::<DecodeEnum>("{\"variant\": \"A\"}", MissingFieldError("fields".to_string()));
|
||||
check_err::<DecodeEnum>(
|
||||
"{\"variant\": \"A\", \"fields\": null}",
|
||||
ExpectedError("Array".to_string(), "null".to_string()),
|
||||
);
|
||||
check_err::<DecodeEnum>(
|
||||
"{\"variant\": \"C\", \"fields\": []}",
|
||||
UnknownVariantError("C".to_string()),
|
||||
);
|
||||
#[should_panic(expected = r#"ExpectedError("Number", "true")"#)]
|
||||
fn test_decode_errors_struct2() {
|
||||
check_err::<DecodeStruct>(r#"{"x": true, "y": true, "z": "", "w": []}"#);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("Boolean", "[]")"#)]
|
||||
fn test_decode_errors_struct3() {
|
||||
check_err::<DecodeStruct>(r#"{"x": 1, "y": [], "z": "", "w": []}"#);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("String", "{}")"#)]
|
||||
fn test_decode_errors_struct4() {
|
||||
check_err::<DecodeStruct>(r#"{"x": 1, "y": true, "z": {}, "w": []}"#);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("Array", "null")"#)]
|
||||
fn test_decode_errors_struct5() {
|
||||
check_err::<DecodeStruct>(r#"{"x": 1, "y": true, "z": "", "w": null}"#);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("Array", "null")"#)]
|
||||
fn test_decode_errors_struct6() {
|
||||
check_err::<DecodeStruct>(r#"{"x": 1, "y": true, "z": ""}"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = r#"MissingFieldError("variant")"#)]
|
||||
fn test_decode_errors_enum1() {
|
||||
check_err::<DecodeEnum>(r#"{}"#);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("String", "1")"#)]
|
||||
fn test_decode_errors_enum2() {
|
||||
check_err::<DecodeEnum>(r#"{"variant": 1}"#);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected = r#"MissingFieldError("fields")"#)]
|
||||
fn test_decode_errors_enum3() {
|
||||
check_err::<DecodeEnum>(r#"{"variant": "A"}"#);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("Array", "null")"#)]
|
||||
fn test_decode_errors_enum4() {
|
||||
check_err::<DecodeEnum>(r#"{"variant": "A", "fields": null}"#);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic(expected = r#"UnknownVariantError("C")"#)]
|
||||
fn test_decode_errors_enum5() {
|
||||
check_err::<DecodeEnum>(r#"{"variant": "C", "fields": []}"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -944,7 +948,7 @@ fn test_hashmap_with_enum_key() {
|
|||
map.insert(Enum::Foo, 0);
|
||||
let result = json::encode(&map).unwrap();
|
||||
assert_eq!(&result[..], r#"{"Foo":0}"#);
|
||||
let decoded: HashMap<Enum, _> = json::decode(&result).unwrap();
|
||||
let decoded: HashMap<Enum, _> = json::decode(&result);
|
||||
assert_eq!(map, decoded);
|
||||
}
|
||||
|
||||
|
@ -957,10 +961,11 @@ fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() {
|
|||
Ok(o) => o,
|
||||
};
|
||||
let mut decoder = Decoder::new(json_obj);
|
||||
let _hm: HashMap<usize, bool> = Decodable::decode(&mut decoder).unwrap();
|
||||
let _hm: HashMap<usize, bool> = Decodable::decode(&mut decoder);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("Number", "a")"#)]
|
||||
fn test_hashmap_with_numeric_key_will_error_with_string_keys() {
|
||||
use std::collections::HashMap;
|
||||
let json_str = "{\"a\":true}";
|
||||
|
@ -969,8 +974,7 @@ fn test_hashmap_with_numeric_key_will_error_with_string_keys() {
|
|||
Ok(o) => o,
|
||||
};
|
||||
let mut decoder = Decoder::new(json_obj);
|
||||
let result: Result<HashMap<usize, bool>, DecoderError> = Decodable::decode(&mut decoder);
|
||||
assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string())));
|
||||
let _: HashMap<usize, bool> = Decodable::decode(&mut decoder);
|
||||
}
|
||||
|
||||
fn assert_stream_equal(src: &str, expected: Vec<(JsonEvent, Vec<StackElement<'_>>)>) {
|
||||
|
|
|
@ -41,7 +41,7 @@ fn check_round_trip<T: Encodable<Encoder> + for<'a> Decodable<Decoder<'a>> + Par
|
|||
let mut decoder = Decoder::new(&data[..], 0);
|
||||
|
||||
for value in values {
|
||||
let decoded = Decodable::decode(&mut decoder).unwrap();
|
||||
let decoded = Decodable::decode(&mut decoder);
|
||||
assert_eq!(value, decoded);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue