diff options
Diffstat (limited to 'compiler/rustc_serialize/src')
| -rw-r--r-- | compiler/rustc_serialize/src/collection_impls.rs | 107 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/json.rs | 321 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/serialize.rs | 185 |
3 files changed, 90 insertions, 523 deletions
diff --git a/compiler/rustc_serialize/src/collection_impls.rs b/compiler/rustc_serialize/src/collection_impls.rs index 02b28f7c626..dee6dc010fe 100644 --- a/compiler/rustc_serialize/src/collection_impls.rs +++ b/compiler/rustc_serialize/src/collection_impls.rs @@ -18,7 +18,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) -> SmallVec<A> { - d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect()) + let len = d.read_usize(); + (0..len).map(|_| Decodable::decode(d)).collect() } } @@ -35,7 +36,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) -> LinkedList<T> { - d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect()) + let len = d.read_usize(); + (0..len).map(|_| Decodable::decode(d)).collect() } } @@ -52,7 +54,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) -> VecDeque<T> { - d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect()) + let len = d.read_usize(); + (0..len).map(|_| Decodable::decode(d)).collect() } } @@ -78,15 +81,14 @@ where V: Decodable<D>, { 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)); - map.insert(key, val); - } - map - }) + let len = d.read_usize(); + let mut map = BTreeMap::new(); + for _ in 0..len { + let key = Decodable::decode(d); + let val = Decodable::decode(d); + map.insert(key, val); + } + map } } @@ -109,13 +111,12 @@ where T: Decodable<D> + PartialEq + Ord, { 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 - }) + let len = d.read_usize(); + let mut set = BTreeSet::new(); + for _ in 0..len { + set.insert(Decodable::decode(d)); + } + set } } @@ -143,16 +144,15 @@ where S: BuildHasher + Default, { 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)); - map.insert(key, val); - } - map - }) + let len = d.read_usize(); + let state = Default::default(); + let mut map = HashMap::with_capacity_and_hasher(len, state); + for _ in 0..len { + let key = Decodable::decode(d); + let val = Decodable::decode(d); + map.insert(key, val); + } + map } } @@ -187,14 +187,13 @@ where S: BuildHasher + Default, { 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 - }) + let len = d.read_usize(); + let state = Default::default(); + let mut set = HashSet::with_capacity_and_hasher(len, state); + for _ in 0..len { + set.insert(Decodable::decode(d)); + } + set } } @@ -222,16 +221,15 @@ where S: BuildHasher + Default, { 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)); - map.insert(key, val); - } - map - }) + let len = d.read_usize(); + let state = Default::default(); + let mut map = indexmap::IndexMap::with_capacity_and_hasher(len, state); + for _ in 0..len { + let key = Decodable::decode(d); + let val = Decodable::decode(d); + map.insert(key, val); + } + map } } @@ -256,14 +254,13 @@ where S: BuildHasher + Default, { 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 - }) + let len = d.read_usize(); + let state = Default::default(); + let mut set = indexmap::IndexSet::with_capacity_and_hasher(len, state); + for _ in 0..len { + set.insert(Decodable::decode(d)); + } + set } } diff --git a/compiler/rustc_serialize/src/json.rs b/compiler/rustc_serialize/src/json.rs index 7e08b18cf48..0cbea3a07a8 100644 --- a/compiler/rustc_serialize/src/json.rs +++ b/compiler/rustc_serialize/src/json.rs @@ -45,12 +45,9 @@ //! //! # Rust Type-based Encoding and Decoding //! -//! Rust provides a mechanism for low boilerplate encoding & decoding of values to and from JSON via -//! the serialization API. -//! To be able to encode a piece of data, it must implement the `serialize::Encodable` trait. -//! To be able to decode a piece of data, it must implement the `serialize::Decodable` trait. -//! The Rust compiler provides an annotation to automatically generate the code for these traits: -//! `#[derive(Decodable, Encodable)]` +//! To be able to encode a piece of data, it must implement the +//! `serialize::Encodable` trait. The `rustc_macros` crate provides an +//! annotation to automatically generate the code for this trait: `#[derive(Encodable)]`. //! //! The JSON API provides an enum `json::Json` and a trait `ToJson` to encode objects. //! The `ToJson` trait provides a `to_json` method to convert an object into a `json::Json` value. @@ -68,11 +65,11 @@ //! //! ```rust //! # #![feature(rustc_private)] -//! use rustc_macros::{Decodable, Encodable}; +//! use rustc_macros::{Encodable}; //! use rustc_serialize::json; //! -//! // Automatically generate `Decodable` and `Encodable` trait implementations -//! #[derive(Decodable, Encodable)] +//! // Automatically generate `Encodable` trait implementations +//! #[derive(Encodable)] //! pub struct TestStruct { //! data_int: u8, //! data_str: String, @@ -87,9 +84,6 @@ //! //! // Serialize using `json::encode` //! let encoded = json::encode(&object).unwrap(); -//! -//! // Deserialize using `json::decode` -//! let decoded: TestStruct = json::decode(&encoded[..]); //! ``` //! //! ## Using the `ToJson` trait @@ -139,12 +133,9 @@ //! //! ```rust //! # #![feature(rustc_private)] -//! use rustc_macros::Decodable; //! use std::collections::BTreeMap; -//! use rustc_serialize::json::{self, Json, ToJson}; +//! use rustc_serialize::json::{Json, ToJson}; //! -//! // Only generate `Decodable` trait implementation -//! #[derive(Decodable)] //! pub struct TestStruct { //! data_int: u8, //! data_str: String, @@ -171,19 +162,14 @@ //! }; //! let json_obj: Json = input_data.to_json(); //! let json_str: String = json_obj.to_string(); -//! -//! // Deserialize like before -//! let decoded: TestStruct = json::decode(&json_str); //! ``` -use self::DecoderError::*; use self::ErrorCode::*; use self::InternalStackElement::*; use self::JsonEvent::*; use self::ParserError::*; use self::ParserState::*; -use std::borrow::Cow; use std::collections::{BTreeMap, HashMap}; use std::mem::swap; use std::num::FpCategory as Fp; @@ -253,21 +239,6 @@ pub enum ParserError { // Builder and Parser have the same errors. pub type BuilderError = ParserError; -#[derive(Clone, PartialEq, Debug)] -pub enum DecoderError { - ParseError(ParserError), - ExpectedError(string::String, string::String), - MissingFieldError(string::String), - UnknownVariantError(string::String), - ApplicationError(string::String), -} - -macro_rules! bad { - ($e:expr) => {{ - panic!("json decode error: {:?}", $e); - }}; -} - #[derive(Copy, Clone, Debug)] pub enum EncoderError { FmtError(fmt::Error), @@ -297,17 +268,6 @@ 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) -> T { - let json = match from_str(s) { - Ok(x) => x, - Err(e) => bad!(ParseError(e)), - }; - - let mut decoder = Decoder::new(json); - crate::Decodable::decode(&mut decoder) -} - /// Shortcut function to encode a `T` into a JSON `String` pub fn encode<T: for<'r> crate::Encodable<Encoder<'r>>>( object: &T, @@ -352,7 +312,6 @@ impl From<fmt::Error> for EncoderError { } pub type EncodeResult = Result<(), EncoderError>; -pub type DecodeResult<T> = Result<T, DecoderError>; fn escape_str(wr: &mut dyn fmt::Write, v: &str) -> EncodeResult { wr.write_str("\"")?; @@ -2162,272 +2121,6 @@ pub fn from_str(s: &str) -> Result<Json, BuilderError> { builder.build() } -/// A structure to decode JSON to values in rust. -pub struct Decoder { - stack: Vec<Json>, -} - -impl Decoder { - /// Creates a new decoder instance for decoding the specified JSON value. - pub fn new(json: Json) -> Decoder { - Decoder { stack: vec![json] } - } - - fn pop(&mut self) -> Json { - self.stack.pop().unwrap() - } -} - -macro_rules! expect { - ($e:expr, Null) => {{ - match $e { - Json::Null => (), - other => bad!(ExpectedError("Null".to_owned(), other.to_string())), - } - }}; - ($e:expr, $t:ident) => {{ - match $e { - 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) -> $ty { - match self.pop() { - 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) => f, - None => bad!(ExpectedError("Number".to_owned(), s)), - }, - value => bad!(ExpectedError("Number".to_owned(), value.to_string())), - } - } - }; -} - -impl crate::Decoder for Decoder { - fn read_unit(&mut self) -> () { - expect!(self.pop(), Null) - } - - read_primitive! { read_usize, usize } - read_primitive! { read_u8, u8 } - read_primitive! { read_u16, u16 } - read_primitive! { read_u32, u32 } - read_primitive! { read_u64, u64 } - read_primitive! { read_u128, u128 } - read_primitive! { read_isize, isize } - read_primitive! { read_i8, i8 } - read_primitive! { read_i16, i16 } - read_primitive! { read_i32, i32 } - read_primitive! { read_i64, i64 } - read_primitive! { read_i128, i128 } - - fn read_f32(&mut self) -> f32 { - self.read_f64() as f32 - } - - fn read_f64(&mut self) -> f64 { - match self.pop() { - 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) => f, - None => bad!(ExpectedError("Number".to_owned(), s)), - } - } - Json::Null => f64::NAN, - value => bad!(ExpectedError("Number".to_owned(), value.to_string())), - } - } - - fn read_bool(&mut self) -> bool { - expect!(self.pop(), Boolean) - } - - 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; - } - bad!(ExpectedError("single character string".to_owned(), s.to_string())); - } - - fn read_str(&mut self) -> Cow<'_, str> { - Cow::Owned(expect!(self.pop(), String)) - } - - fn read_raw_bytes_into(&mut self, s: &mut [u8]) { - for c in s.iter_mut() { - *c = self.read_u8(); - } - } - - fn read_enum<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Decoder) -> T, - { - f(self) - } - - fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F) -> T - where - 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) => 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) => bad!(ExpectedError("Array".to_owned(), val.to_string())), - None => bad!(MissingFieldError("fields".to_owned())), - } - n - } - json => bad!(ExpectedError("String or Object".to_owned(), json.to_string())), - }; - let Some(idx) = names.iter().position(|n| *n == &name[..]) else { - bad!(UnknownVariantError(name)); - }; - f(self, idx) - } - - fn read_enum_variant_arg<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Decoder) -> T, - { - f(self) - } - - fn read_struct<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Decoder) -> T, - { - let value = f(self); - self.pop(); - value - } - - fn read_struct_field<T, F>(&mut self, name: &str, f: F) -> T - where - F: FnOnce(&mut Decoder) -> T, - { - 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); - f(self) - } - Some(json) => { - self.stack.push(json); - f(self) - } - }; - self.stack.push(Json::Object(obj)); - value - } - - fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> T - where - F: FnOnce(&mut Decoder) -> T, - { - self.read_seq(move |d, len| { - if len == tuple_len { - f(d) - } else { - bad!(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len))); - } - }) - } - - fn read_tuple_arg<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Decoder) -> T, - { - self.read_seq_elt(f) - } - - fn read_option<T, F>(&mut self, mut f: F) -> T - where - F: FnMut(&mut Decoder, bool) -> T, - { - match self.pop() { - Json::Null => f(self, false), - value => { - self.stack.push(value); - f(self, true) - } - } - } - - fn read_seq<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Decoder, usize) -> T, - { - 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) -> T - where - F: FnOnce(&mut Decoder) -> T, - { - f(self) - } - - fn read_map<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Decoder, usize) -> T, - { - let obj = expect!(self.pop(), Object); - let len = obj.len(); - for (key, value) in obj { - self.stack.push(value); - self.stack.push(Json::String(key)); - } - f(self, len) - } - - fn read_map_elt_key<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Decoder) -> T, - { - f(self) - } - - fn read_map_elt_val<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Decoder) -> T, - { - f(self) - } -} - /// A trait for converting values to JSON pub trait ToJson { /// Converts the value of `self` to an instance of JSON diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index a6172403fd6..a012be2857e 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -200,118 +200,6 @@ pub trait Decoder { 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) -> T - where - F: FnOnce(&mut Self) -> T, - { - f(self) - } - - #[inline] - fn read_enum_variant<T, F>(&mut self, _names: &[&str], mut f: F) -> T - where - F: FnMut(&mut Self, usize) -> T, - { - let disr = self.read_usize(); - f(self, disr) - } - - #[inline] - fn read_enum_variant_arg<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { - f(self) - } - - #[inline] - fn read_struct<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { - f(self) - } - - #[inline] - fn read_struct_field<T, F>(&mut self, _f_name: &str, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { - f(self) - } - - #[inline] - fn read_tuple<T, F>(&mut self, _len: usize, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { - f(self) - } - - #[inline] - fn read_tuple_arg<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { - f(self) - } - - // Specialized types: - fn read_option<T, F>(&mut self, mut f: F) -> T - where - 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), - _ => panic!("read_option: expected 0 for None or 1 for Some"), - }) - }) - } - - fn read_seq<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Self, usize) -> T, - { - let len = self.read_usize(); - f(self, len) - } - - #[inline] - fn read_seq_elt<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { - f(self) - } - - fn read_map<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Self, usize) -> T, - { - let len = self.read_usize(); - f(self, len) - } - - #[inline] - fn read_map_elt_key<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { - f(self) - } - - #[inline] - fn read_map_elt_val<T, F>(&mut self, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { - f(self) - } } /// Trait for types that can be serialized @@ -493,22 +381,18 @@ 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) -> Vec<T> { - d.read_seq(|d, len| { - // 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); + let len = d.read_usize(); + // 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), Decodable::decode(d)); } - vec - }) + vec.set_len(len); + } + vec } } @@ -521,14 +405,13 @@ 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) -> [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 - }) + let len = d.read_usize(); + assert!(len == N); + let mut v = [0u8; N]; + for i in 0..len { + v[i] = Decodable::decode(d); + } + v } } @@ -563,7 +446,11 @@ 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) -> Option<T> { - d.read_option(|d, b| if b { Some(Decodable::decode(d)) } else { None }) + match d.read_usize() { + 0 => None, + 1 => Some(Decodable::decode(d)), + _ => panic!("Encountered invalid discriminant while decoding `Option`."), + } } } @@ -582,13 +469,11 @@ 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<T1, T2> { - d.read_enum(|d| { - d.read_enum_variant(&["Ok", "Err"], |d, disr| match disr { - 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`."), - }) - }) + match d.read_usize() { + 0 => Ok(T1::decode(d)), + 1 => Err(T2::decode(d)), + _ => panic!("Encountered invalid discriminant while decoding `Result`."), + } } } @@ -613,24 +498,16 @@ macro_rules! tuple { () => (); ( $($name:ident,)+ ) => ( impl<D: Decoder, $($name: Decodable<D>),+> Decodable<D> for ($($name,)+) { - #[allow(non_snake_case)] fn decode(d: &mut D) -> ($($name,)+) { - let len: usize = count!($($name)+); - d.read_tuple(len, |d| { - let ret = ($(d.read_tuple_arg(|d| -> $name { - Decodable::decode(d) - }),)+); - ret - }) + ($({ let element: $name = Decodable::decode(d); element },)+) } } impl<S: Encoder, $($name: Encodable<S>),+> Encodable<S> for ($($name,)+) { #[allow(non_snake_case)] fn encode(&self, s: &mut S) -> Result<(), S::Error> { let ($(ref $name,)+) = *self; - let mut n = 0; - $(let $name = $name; n += 1;)+ - s.emit_tuple(n, |s| { + let len: usize = count!($($name)+); + s.emit_tuple(len, |s| { let mut i = 0; $(s.emit_tuple_arg({ i+=1; i-1 }, |s| $name.encode(s))?;)+ Ok(()) |
