Remove support for JSON deserialization to Rust
This is no longer used by the compiler itself, and removing this support opens the door to massively simplifying the Decodable/Decoder API by dropping the self-describing deserialization support (necessary for JSON).
This commit is contained in:
parent
45e2c2881d
commit
60b71f56e7
9 changed files with 46 additions and 718 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue