mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-27 13:27:56 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f0d3453d8 | |||
| b27a27ce22 | |||
| 80c0600657 | |||
| 77f9e63661 | |||
| b78f434086 |
@@ -5,6 +5,7 @@ cache: cargo
|
|||||||
# run builds for all the trains (and more)
|
# run builds for all the trains (and more)
|
||||||
rust:
|
rust:
|
||||||
- 1.13.0
|
- 1.13.0
|
||||||
|
- 1.15.0
|
||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.44" # remember to update html_root_url
|
version = "1.0.45" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Serde types in rustdoc of other crates get linked to here.
|
// Serde types in rustdoc of other crates get linked to here.
|
||||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.44")]
|
#![doc(html_root_url = "https://docs.rs/serde/1.0.45")]
|
||||||
// Support using Serde without the standard library!
|
// Support using Serde without the standard library!
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
// Unstable functionality only if the user asks for it. For tracking and
|
// Unstable functionality only if the user asks for it. For tracking and
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.44" # remember to update html_root_url
|
version = "1.0.45" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use bound;
|
|||||||
use fragment::{Expr, Fragment, Match, Stmts};
|
use fragment::{Expr, Fragment, Match, Stmts};
|
||||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
use internals::{self, attr};
|
use internals::{self, attr};
|
||||||
|
use pretend;
|
||||||
use try;
|
use try;
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
@@ -37,11 +38,13 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
|
|||||||
|
|
||||||
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
||||||
let vis = &input.vis;
|
let vis = &input.vis;
|
||||||
|
let used = pretend::pretend_used(&cont);
|
||||||
quote! {
|
quote! {
|
||||||
impl #de_impl_generics #ident #ty_generics #where_clause {
|
impl #de_impl_generics #ident #ty_generics #where_clause {
|
||||||
#vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
|
#vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
|
||||||
where __D: _serde::Deserializer<#delife>
|
where __D: _serde::Deserializer<#delife>
|
||||||
{
|
{
|
||||||
|
#used
|
||||||
#body
|
#body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
//!
|
//!
|
||||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.44")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.45")]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding)
|
allow(enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding)
|
||||||
@@ -49,6 +49,7 @@ mod bound;
|
|||||||
mod fragment;
|
mod fragment;
|
||||||
|
|
||||||
mod de;
|
mod de;
|
||||||
|
mod pretend;
|
||||||
mod ser;
|
mod ser;
|
||||||
mod try;
|
mod try;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,145 @@
|
|||||||
|
use proc_macro2::Span;
|
||||||
|
use quote::Tokens;
|
||||||
|
use syn::Ident;
|
||||||
|
|
||||||
|
use internals::ast::{Container, Data, Field, Style};
|
||||||
|
|
||||||
|
// Suppress dead_code warnings that would otherwise appear when using a remote
|
||||||
|
// derive. Other than this pretend code, a struct annotated with remote derive
|
||||||
|
// never has its fields referenced and an enum annotated with remote derive
|
||||||
|
// never has its variants constructed.
|
||||||
|
//
|
||||||
|
// warning: field is never used: `i`
|
||||||
|
// --> src/main.rs:4:20
|
||||||
|
// |
|
||||||
|
// 4 | struct StructDef { i: i32 }
|
||||||
|
// | ^^^^^^
|
||||||
|
//
|
||||||
|
// warning: variant is never constructed: `V`
|
||||||
|
// --> src/main.rs:8:16
|
||||||
|
// |
|
||||||
|
// 8 | enum EnumDef { V }
|
||||||
|
// | ^
|
||||||
|
//
|
||||||
|
pub fn pretend_used(cont: &Container) -> Tokens {
|
||||||
|
let pretend_fields = pretend_fields_used(cont);
|
||||||
|
let pretend_variants = pretend_variants_used(cont);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#pretend_fields
|
||||||
|
#pretend_variants
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For structs with named fields, expands to:
|
||||||
|
//
|
||||||
|
// match None::<T> {
|
||||||
|
// Some(T { a: ref __v0, b: ref __v1 }) => {}
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// For enums, expands to the following but only including struct variants:
|
||||||
|
//
|
||||||
|
// match None::<T> {
|
||||||
|
// Some(T::A { a: ref __v0 }) => {}
|
||||||
|
// Some(T::B { b: ref __v0 }) => {}
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The `ref` is important in case the user has written a Drop impl on their
|
||||||
|
// type. Rust does not allow destructuring a struct or enum that has a Drop
|
||||||
|
// impl.
|
||||||
|
fn pretend_fields_used(cont: &Container) -> Tokens {
|
||||||
|
let type_ident = cont.ident;
|
||||||
|
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||||
|
|
||||||
|
let patterns = match cont.data {
|
||||||
|
Data::Enum(ref variants) => {
|
||||||
|
variants.iter()
|
||||||
|
.filter_map(|variant| match variant.style {
|
||||||
|
Style::Struct => {
|
||||||
|
let variant_ident = variant.ident;
|
||||||
|
let pat = struct_pattern(&variant.fields);
|
||||||
|
Some(quote!(#type_ident::#variant_ident #pat))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
Data::Struct(Style::Struct, ref fields) => {
|
||||||
|
let pat = struct_pattern(fields);
|
||||||
|
vec![quote!(#type_ident #pat)]
|
||||||
|
}
|
||||||
|
Data::Struct(_, _) => {
|
||||||
|
return quote!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
match _serde::export::None::<#type_ident #ty_generics> {
|
||||||
|
#(
|
||||||
|
_serde::export::Some(#patterns) => {}
|
||||||
|
)*
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expands to one of these per enum variant:
|
||||||
|
//
|
||||||
|
// match None {
|
||||||
|
// Some((__v0, __v1,)) => {
|
||||||
|
// let _ = E::V { a: __v0, b: __v1 };
|
||||||
|
// }
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
fn pretend_variants_used(cont: &Container) -> Tokens {
|
||||||
|
let variants = match cont.data {
|
||||||
|
Data::Enum(ref variants) => variants,
|
||||||
|
Data::Struct(_, _) => {
|
||||||
|
return quote!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let type_ident = cont.ident;
|
||||||
|
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||||
|
let turbofish = ty_generics.as_turbofish();
|
||||||
|
|
||||||
|
let cases = variants.iter()
|
||||||
|
.map(|variant| {
|
||||||
|
let variant_ident = variant.ident;
|
||||||
|
let ref placeholders = (0..variant.fields.len())
|
||||||
|
.map(|i| Ident::new(&format!("__v{}", i), Span::call_site()))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let pat = match variant.style {
|
||||||
|
Style::Struct => {
|
||||||
|
let names = variant.fields.iter().map(|field| field.ident);
|
||||||
|
quote!({ #(#names: #placeholders),* })
|
||||||
|
}
|
||||||
|
Style::Tuple | Style::Newtype => {
|
||||||
|
quote!(( #(#placeholders),* ))
|
||||||
|
}
|
||||||
|
Style::Unit => quote!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
match _serde::export::None {
|
||||||
|
_serde::export::Some((#(#placeholders,)*)) => {
|
||||||
|
let _ = #type_ident::#variant_ident #turbofish #pat;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
quote!(#(#cases)*)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn struct_pattern(fields: &[Field]) -> Tokens {
|
||||||
|
let names = fields.iter().map(|field| field.ident);
|
||||||
|
let placeholders = (0..fields.len())
|
||||||
|
.map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
|
||||||
|
quote!({ #(#names: ref #placeholders),* })
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ use bound;
|
|||||||
use fragment::{Fragment, Match, Stmts};
|
use fragment::{Fragment, Match, Stmts};
|
||||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
use internals::{attr, Ctxt};
|
use internals::{attr, Ctxt};
|
||||||
|
use pretend;
|
||||||
use try;
|
use try;
|
||||||
|
|
||||||
use std::u32;
|
use std::u32;
|
||||||
@@ -33,11 +34,13 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
|
|||||||
|
|
||||||
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
||||||
let vis = &input.vis;
|
let vis = &input.vis;
|
||||||
|
let used = pretend::pretend_used(&cont);
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_generics #ident #ty_generics #where_clause {
|
impl #impl_generics #ident #ty_generics #where_clause {
|
||||||
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||||
where __S: _serde::Serializer
|
where __S: _serde::Serializer
|
||||||
{
|
{
|
||||||
|
#used
|
||||||
#body
|
#body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_test"
|
name = "serde_test"
|
||||||
version = "1.0.44" # remember to update html_root_url
|
version = "1.0.45" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||||
|
|||||||
@@ -155,7 +155,7 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.44")]
|
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.45")]
|
||||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||||
// Whitelisted clippy lints
|
// Whitelisted clippy lints
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
|
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
|
||||||
|
|||||||
@@ -333,9 +333,7 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(untagged, remote = "Or")]
|
#[serde(untagged, remote = "Or")]
|
||||||
enum OrDef<A, B> {
|
enum OrDef<A, B> {
|
||||||
#[allow(dead_code)]
|
|
||||||
A(A),
|
A(A),
|
||||||
#[allow(dead_code)]
|
|
||||||
B(B),
|
B(B),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,10 +160,8 @@ struct StructPrivDef {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::StructPub")]
|
#[serde(remote = "remote::StructPub")]
|
||||||
struct StructPubDef {
|
struct StructPubDef {
|
||||||
#[allow(dead_code)]
|
|
||||||
a: u8,
|
a: u8,
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[serde(with = "UnitDef")]
|
#[serde(with = "UnitDef")]
|
||||||
b: remote::Unit,
|
b: remote::Unit,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user