1
Fork 0

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:
Nicholas Nethercote 2022-01-18 13:22:50 +11:00
parent 88600a6d7f
commit 416399dc10
39 changed files with 726 additions and 781 deletions

View file

@ -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()
}
}

View file

@ -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

View file

@ -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)
}
}

View file

@ -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))
}
}

View file

@ -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<'_>>)>) {

View file

@ -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);
}
}