diff options
| author | bors <bors@rust-lang.org> | 2022-02-22 07:54:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-02-22 07:54:22 +0000 |
| commit | 58a721af9f818bdf57f86448557b45c5ae19a3ef (patch) | |
| tree | 086ddac67129cf7c2503daae81f5b0e03706ba81 /compiler/rustc_serialize/src | |
| parent | b8967b0d52a2ba5f0c9da0da03e78ccba5534e4a (diff) | |
| parent | c6ad61a1bd2d82f4ac8f7e3c069caa1c2f52c1b4 (diff) | |
| download | rust-58a721af9f818bdf57f86448557b45c5ae19a3ef.tar.gz rust-58a721af9f818bdf57f86448557b45c5ae19a3ef.zip | |
Auto merge of #93839 - Mark-Simulacrum:delete-json-rust-deserialization, r=nnethercote
Simplify rustc_serialize by dropping support for decoding into JSON This PR currently bundles two (somewhat separate) tasks. First, it removes the JSON Decoder trait impl, which permitted going from JSON to Rust structs. For now, we keep supporting JSON deserialization, but only to `Json` (an equivalent of serde_json::Value). The primary hard to remove user there is for custom targets -- which need some form of JSON deserialization -- but they already have a custom ad-hoc pass for moving from Json to a Rust struct. A [comment](https://github.com/rust-lang/rust/blob/e7aca895980f25f6d2d3c48e10fd04656764d1e4/compiler/rustc_target/src/spec/mod.rs#L1653) there suggests that it would be impractical to move them to a Decodable-based impl, at least without backwards compatibility concerns. I suspect that if we were widely breaking compat there, it would make sense to use serde_json at this point which would produce better error messages; the types in rustc_target are relatively isolated so we would not particularly suffer from using serde_derive. The second part of the PR (all but the first commit) is to simplify the Decoder API by removing the non-primitive `read_*` functions. These primarily add indirection (through a closure), which doesn't directly cause a performance issue (the unique closure types essentially guarantee monomorphization), but does increase the amount of work rustc and LLVM need to do. This could be split out to a separate PR, but is included here in part to help motivate the first part. Future work might consist of: * Specializing enum discriminant encoding to avoid leb128 for small enums (since we know the variant count, we can directly use read/write u8 in almost all cases) * Adding new methods to support faster deserialization (e.g., access to the underlying byte stream) * Currently these are somewhat ad-hoc supported by specializations for e.g. `Vec<u8>`, but other types which could benefit don't today. * Removing the Decoder trait entirely in favor of a concrete type -- today, we only really have one impl of it modulo wrappers used for specialization-based dispatch. Highly recommend review with whitespace changes off, as the removal of closures frequently causes things to be de-indented.
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(()) |
