mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
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
@ -5,17 +5,12 @@ use rustc_span::source_map::{FilePathMapping, SourceMap};
|
||||
|
||||
use crate::emitter::{ColorConfig, HumanReadableErrorType};
|
||||
use crate::Handler;
|
||||
use rustc_serialize::json::decode;
|
||||
use rustc_serialize::json;
|
||||
use rustc_span::{BytePos, Span};
|
||||
|
||||
use std::str;
|
||||
|
||||
#[derive(Decodable, Debug, PartialEq, Eq)]
|
||||
struct TestData {
|
||||
spans: Vec<SpanTestData>,
|
||||
}
|
||||
|
||||
#[derive(Decodable, Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
struct SpanTestData {
|
||||
pub byte_start: u32,
|
||||
pub byte_end: u32,
|
||||
@ -41,8 +36,6 @@ impl<T: Write> Write for Shared<T> {
|
||||
|
||||
/// Test the span yields correct positions in JSON.
|
||||
fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
|
||||
let expected_output = TestData { spans: vec![expected_output] };
|
||||
|
||||
rustc_span::create_default_session_globals_then(|| {
|
||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned());
|
||||
@ -64,9 +57,19 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
|
||||
|
||||
let bytes = output.lock().unwrap();
|
||||
let actual_output = str::from_utf8(&bytes).unwrap();
|
||||
let actual_output: TestData = decode(actual_output);
|
||||
|
||||
assert_eq!(expected_output, actual_output)
|
||||
let actual_output = json::from_str(&actual_output).unwrap();
|
||||
let spans = actual_output["spans"].as_array().unwrap();
|
||||
assert_eq!(spans.len(), 1);
|
||||
let obj = &spans[0];
|
||||
let actual_output = SpanTestData {
|
||||
byte_start: obj["byte_start"].as_u64().unwrap() as u32,
|
||||
byte_end: obj["byte_end"].as_u64().unwrap() as u32,
|
||||
line_start: obj["line_start"].as_u64().unwrap() as u32,
|
||||
line_end: obj["line_end"].as_u64().unwrap() as u32,
|
||||
column_start: obj["column_start"].as_u64().unwrap() as u32,
|
||||
column_end: obj["column_end"].as_u64().unwrap() as u32,
|
||||
};
|
||||
assert_eq!(expected_output, actual_output);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -4,61 +4,35 @@ use json::ErrorCode::*;
|
||||
use json::Json::*;
|
||||
use json::JsonEvent::*;
|
||||
use json::ParserError::*;
|
||||
use json::{from_str, Decoder, Encoder, EncoderError, Json, JsonEvent, Parser, StackElement};
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use json::{from_str, Encoder, EncoderError, Json, JsonEvent, Parser, StackElement};
|
||||
use rustc_macros::Encodable;
|
||||
use rustc_serialize::json;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use rustc_serialize::Encodable;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::io::prelude::*;
|
||||
use std::string;
|
||||
use Animal::*;
|
||||
|
||||
#[derive(Decodable, Eq, PartialEq, Debug)]
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
struct OptionData {
|
||||
opt: Option<usize>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_option_none() {
|
||||
let s = "{}";
|
||||
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);
|
||||
assert_eq!(obj, OptionData { opt: Some(10) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[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)]
|
||||
#[derive(PartialEq, Encodable, Debug)]
|
||||
enum Animal {
|
||||
Dog,
|
||||
Frog(string::String, isize),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Encodable, Decodable, Debug)]
|
||||
#[derive(PartialEq, Encodable, Debug)]
|
||||
struct Inner {
|
||||
a: (),
|
||||
b: usize,
|
||||
c: Vec<string::String>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Encodable, Decodable, Debug)]
|
||||
#[derive(PartialEq, Encodable, Debug)]
|
||||
struct Outer {
|
||||
inner: Vec<Inner>,
|
||||
}
|
||||
@ -323,18 +297,6 @@ fn test_read_identifiers() {
|
||||
assert_eq!(from_str(" false "), Ok(Boolean(false)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_identifiers() {
|
||||
let v: () = json::decode("null");
|
||||
assert_eq!(v, ());
|
||||
|
||||
let v: bool = json::decode("true");
|
||||
assert_eq!(v, true);
|
||||
|
||||
let v: bool = json::decode("false");
|
||||
assert_eq!(v, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_number() {
|
||||
assert_eq!(from_str("+"), Err(SyntaxError(InvalidSyntax, 1, 1)));
|
||||
@ -363,45 +325,6 @@ fn test_read_number() {
|
||||
assert_eq!(from_str("18446744073709551615"), Ok(U64(u64::MAX)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = r#"ExpectedError("Integer", "765.25")"#)]
|
||||
fn test_decode_numbers() {
|
||||
let v: f64 = json::decode("3");
|
||||
assert_eq!(v, 3.0);
|
||||
|
||||
let v: f64 = json::decode("3.1");
|
||||
assert_eq!(v, 3.1);
|
||||
|
||||
let v: f64 = json::decode("-1.2");
|
||||
assert_eq!(v, -1.2);
|
||||
|
||||
let v: f64 = json::decode("0.4");
|
||||
assert_eq!(v, 0.4);
|
||||
|
||||
let v: f64 = json::decode("0.4e5");
|
||||
assert_eq!(v, 0.4e5);
|
||||
|
||||
let v: f64 = json::decode("0.4e15");
|
||||
assert_eq!(v, 0.4e15);
|
||||
|
||||
let v: f64 = json::decode("0.4e-01");
|
||||
assert_eq!(v, 0.4e-01);
|
||||
|
||||
let v: u64 = json::decode("0");
|
||||
assert_eq!(v, 0);
|
||||
|
||||
let v: u64 = json::decode("18446744073709551615");
|
||||
assert_eq!(v, u64::MAX);
|
||||
|
||||
let v: i64 = json::decode("-9223372036854775808");
|
||||
assert_eq!(v, i64::MIN);
|
||||
|
||||
let v: i64 = json::decode("9223372036854775807");
|
||||
assert_eq!(v, i64::MAX);
|
||||
|
||||
json::decode::<i64>("765.25");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_str() {
|
||||
assert_eq!(from_str("\""), Err(SyntaxError(EOFWhileParsingString, 1, 2)));
|
||||
@ -419,26 +342,6 @@ fn test_read_str() {
|
||||
assert_eq!(from_str("\"\\uAB12\""), Ok(String("\u{AB12}".to_string())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_str() {
|
||||
let s = [
|
||||
("\"\"", ""),
|
||||
("\"foo\"", "foo"),
|
||||
("\"\\\"\"", "\""),
|
||||
("\"\\b\"", "\x08"),
|
||||
("\"\\n\"", "\n"),
|
||||
("\"\\r\"", "\r"),
|
||||
("\"\\t\"", "\t"),
|
||||
("\"\\u12ab\"", "\u{12ab}"),
|
||||
("\"\\uAB12\"", "\u{AB12}"),
|
||||
];
|
||||
|
||||
for (i, o) in s {
|
||||
let v: string::String = json::decode(i);
|
||||
assert_eq!(v, o);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_array() {
|
||||
assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2)));
|
||||
@ -457,45 +360,6 @@ fn test_read_array() {
|
||||
assert_eq!(from_str("[2, [4, 1]]"), Ok(Array(vec![U64(2), Array(vec![U64(4), U64(1)])])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_array() {
|
||||
let v: Vec<()> = json::decode("[]");
|
||||
assert_eq!(v, []);
|
||||
|
||||
let v: Vec<()> = json::decode("[null]");
|
||||
assert_eq!(v, [()]);
|
||||
|
||||
let v: Vec<bool> = json::decode("[true]");
|
||||
assert_eq!(v, [true]);
|
||||
|
||||
let v: Vec<isize> = json::decode("[3, 1]");
|
||||
assert_eq!(v, [3, 1]);
|
||||
|
||||
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]");
|
||||
assert_eq!(t, (1, 2, 3));
|
||||
|
||||
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() {
|
||||
json::decode::<(usize, string::String)>("[1, 2]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_decode_tuple_malformed_length() {
|
||||
json::decode::<(usize, usize)>("[1, 2, 3]");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_object() {
|
||||
assert_eq!(from_str("{"), Err(SyntaxError(EOFWhileParsingObject, 1, 2)));
|
||||
@ -552,143 +416,11 @@ fn test_read_object() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_struct() {
|
||||
let s = "{
|
||||
\"inner\": [
|
||||
{ \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] }
|
||||
]
|
||||
}";
|
||||
|
||||
let v: Outer = json::decode(s);
|
||||
assert_eq!(
|
||||
v,
|
||||
Outer { inner: vec![Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }] }
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Decodable)]
|
||||
struct FloatStruct {
|
||||
f: f64,
|
||||
a: Vec<f64>,
|
||||
}
|
||||
#[test]
|
||||
fn test_decode_struct_with_nan() {
|
||||
let s = "{\"f\":null,\"a\":[null,123]}";
|
||||
let obj: FloatStruct = json::decode(s);
|
||||
assert!(obj.f.is_nan());
|
||||
assert!(obj.a[0].is_nan());
|
||||
assert_eq!(obj.a[1], 123f64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_option() {
|
||||
let value: Option<string::String> = json::decode("null");
|
||||
assert_eq!(value, None);
|
||||
|
||||
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\"");
|
||||
assert_eq!(value, Dog);
|
||||
|
||||
let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}";
|
||||
let value: Animal = json::decode(s);
|
||||
assert_eq!(value, Frog("Henry".to_string(), 349));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_map() {
|
||||
let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
|
||||
\"fields\":[\"Henry\", 349]}}";
|
||||
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)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiline_errors() {
|
||||
assert_eq!(from_str("{\n \"foo\":\n \"bar\""), Err(SyntaxError(EOFWhileParsingObject, 3, 8)));
|
||||
}
|
||||
|
||||
#[derive(Decodable)]
|
||||
#[allow(dead_code)]
|
||||
struct DecodeStruct {
|
||||
x: f64,
|
||||
y: bool,
|
||||
z: string::String,
|
||||
w: Vec<DecodeStruct>,
|
||||
}
|
||||
#[derive(Decodable)]
|
||||
enum DecodeEnum {
|
||||
A(f64),
|
||||
B(string::String),
|
||||
}
|
||||
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]
|
||||
#[should_panic(expected = r#"ExpectedError("Object", "[]")"#)]
|
||||
fn test_decode_errors_struct1() {
|
||||
check_err::<DecodeStruct>("[]");
|
||||
}
|
||||
#[test]
|
||||
#[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]
|
||||
fn test_find() {
|
||||
let json_value = from_str("{\"dog\" : \"cat\"}").unwrap();
|
||||
@ -938,7 +670,7 @@ fn test_prettyencoder_indent_level_param() {
|
||||
#[test]
|
||||
fn test_hashmap_with_enum_key() {
|
||||
use std::collections::HashMap;
|
||||
#[derive(Encodable, Eq, Hash, PartialEq, Decodable, Debug)]
|
||||
#[derive(Encodable, Eq, Hash, PartialEq, Debug)]
|
||||
enum Enum {
|
||||
Foo,
|
||||
#[allow(dead_code)]
|
||||
@ -948,33 +680,6 @@ 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);
|
||||
assert_eq!(map, decoded);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() {
|
||||
use std::collections::HashMap;
|
||||
let json_str = "{\"1\":true}";
|
||||
let json_obj = match from_str(json_str) {
|
||||
Err(_) => panic!("Unable to parse json_str: {:?}", json_str),
|
||||
Ok(o) => o,
|
||||
};
|
||||
let mut decoder = Decoder::new(json_obj);
|
||||
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}";
|
||||
let json_obj = match from_str(json_str) {
|
||||
Err(_) => panic!("Unable to parse json_str: {:?}", json_str),
|
||||
Ok(o) => o,
|
||||
};
|
||||
let mut decoder = Decoder::new(json_obj);
|
||||
let _: HashMap<usize, bool> = Decodable::decode(&mut decoder);
|
||||
}
|
||||
|
||||
fn assert_stream_equal(src: &str, expected: Vec<(JsonEvent, Vec<StackElement<'_>>)>) {
|
||||
|
@ -7,7 +7,7 @@ extern crate rustc_macros;
|
||||
extern crate rustc_serialize;
|
||||
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use rustc_serialize::json;
|
||||
use rustc_serialize::opaque;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
|
||||
#[derive(Encodable, Decodable)]
|
||||
@ -17,7 +17,9 @@ struct A {
|
||||
|
||||
fn main() {
|
||||
let obj = A { foo: Box::new([true, false]) };
|
||||
let s = json::encode(&obj).unwrap();
|
||||
let obj2: A = json::decode(&s);
|
||||
let mut encoder = opaque::Encoder::new(vec![]);
|
||||
obj.encode(&mut encoder).unwrap();
|
||||
let mut decoder = opaque::Decoder::new(&encoder.data, 0);
|
||||
let obj2 = A::decode(&mut decoder);
|
||||
assert_eq!(obj.foo, obj2.foo);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ extern crate rustc_macros;
|
||||
extern crate rustc_serialize;
|
||||
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use rustc_serialize::json;
|
||||
use rustc_serialize::opaque;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
@ -26,8 +26,10 @@ struct B {
|
||||
|
||||
fn main() {
|
||||
let obj = B { foo: Cell::new(true), bar: RefCell::new(A { baz: 2 }) };
|
||||
let s = json::encode(&obj).unwrap();
|
||||
let obj2: B = json::decode(&s);
|
||||
let mut encoder = opaque::Encoder::new(vec![]);
|
||||
obj.encode(&mut encoder).unwrap();
|
||||
let mut decoder = opaque::Decoder::new(&encoder.data, 0);
|
||||
let obj2 = B::decode(&mut decoder);
|
||||
assert_eq!(obj.foo.get(), obj2.foo.get());
|
||||
assert_eq!(obj.bar.borrow().baz, obj2.bar.borrow().baz);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ extern crate rustc_macros;
|
||||
extern crate rustc_serialize;
|
||||
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
use rustc_serialize::json;
|
||||
use rustc_serialize::opaque;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
|
||||
#[derive(Encodable, Decodable, PartialEq, Debug)]
|
||||
@ -16,11 +16,9 @@ struct UnitLikeStruct;
|
||||
|
||||
pub fn main() {
|
||||
let obj = UnitLikeStruct;
|
||||
let json_str: String = json::encode(&obj).unwrap();
|
||||
|
||||
let json_object = json::from_str(&json_str);
|
||||
let mut decoder = json::Decoder::new(json_object.unwrap());
|
||||
let mut decoded_obj: UnitLikeStruct = Decodable::decode(&mut decoder);
|
||||
|
||||
assert_eq!(obj, decoded_obj);
|
||||
let mut encoder = opaque::Encoder::new(vec![]);
|
||||
obj.encode(&mut encoder).unwrap();
|
||||
let mut decoder = opaque::Decoder::new(&encoder.data, 0);
|
||||
let obj2 = UnitLikeStruct::decode(&mut decoder);
|
||||
assert_eq!(obj, obj2);
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate rustc_serialize;
|
||||
|
||||
use rustc_serialize::{json, Decodable, Encodable};
|
||||
use std::fmt::Display;
|
||||
|
||||
pub trait Entity: Decodable<json::Decoder> + for<'a> Encodable<json::Encoder<'a>> + Sized {
|
||||
type Key: Clone
|
||||
+ Decodable<json::Decoder>
|
||||
+ for<'a> Encodable<json::Encoder<'a>>
|
||||
+ ToString
|
||||
+ Display
|
||||
+ Eq
|
||||
+ Ord
|
||||
+ Sized;
|
||||
|
||||
fn id(&self) -> Self::Key;
|
||||
|
||||
fn find_by_id(id: Self::Key) -> Option<Self>;
|
||||
}
|
||||
|
||||
pub struct DbRef<E: Entity> {
|
||||
pub id: E::Key,
|
||||
}
|
||||
|
||||
impl<E> DbRef<E>
|
||||
where
|
||||
E: Entity,
|
||||
{
|
||||
fn get(self) -> Option<E> {
|
||||
E::find_by_id(self.id)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,19 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate rustc_serialize;
|
||||
|
||||
use rustc_serialize::{json, Decodable};
|
||||
|
||||
trait JD: Decodable<json::Decoder> {}
|
||||
|
||||
fn exec<T: JD>() {
|
||||
let doc = json::from_str("").unwrap();
|
||||
let mut decoder = json::Decoder::new(doc);
|
||||
let _v: T = Decodable::decode(&mut decoder);
|
||||
panic!()
|
||||
}
|
||||
|
||||
pub fn main() {}
|
@ -1,17 +0,0 @@
|
||||
// run-pass
|
||||
// Issue #4036: Test for an issue that arose around fixing up type inference
|
||||
// byproducts in vtable records.
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate rustc_serialize;
|
||||
|
||||
use rustc_serialize::{json, Decodable};
|
||||
|
||||
pub fn main() {
|
||||
let json = json::from_str("[1]").unwrap();
|
||||
let mut decoder = json::Decoder::new(json);
|
||||
let _x: Vec<isize> = Decodable::decode(&mut decoder);
|
||||
}
|
Loading…
Reference in New Issue
Block a user