mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-23 23:27:59 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 930401b0dd | |||
| cb6eaea151 | |||
| b6f339ca36 | |||
| 2a5caea1a8 | |||
| b9f93f99aa | |||
| eb5cd476ba | |||
| 8478a3b7dd | |||
| dbb909136e | |||
| ad8dd4148b | |||
| f91d2ed9ae | |||
| 9497463718 | |||
| 46e9ecfcdd | |||
| e9c399c822 | |||
| b9dbfcb4ac | |||
| c270e27a4d | |||
| 0307f604ea | |||
| 8939af48fe | |||
| fa5d58cd00 | |||
| 1a3cf4b3c1 | |||
| 7d96352e96 | |||
| 111ecc5d8c | |||
| edd6fe954b | |||
| a20e9249c5 | |||
| b1353a99cd | |||
| c59e876bb3 | |||
| 7f1e697c0d | |||
| 373edcd055 | |||
| f0b5c4f857 | |||
| 3035d4fa34 | |||
| 60ac737439 | |||
| a95b0d301e | |||
| 951ca5ace0 | |||
| adf05a5bf6 | |||
| 5f9fffa53e |
@@ -26,6 +26,7 @@ jobs:
|
||||
with:
|
||||
name: Cargo.lock
|
||||
path: Cargo.lock
|
||||
continue-on-error: true
|
||||
|
||||
windows:
|
||||
name: Test suite (windows)
|
||||
@@ -51,6 +52,7 @@ jobs:
|
||||
toolchain: ${{matrix.rust}}
|
||||
- run: cd serde && cargo build --features rc
|
||||
- run: cd serde && cargo build --no-default-features
|
||||
- run: cd test_suite/no_std && cargo build
|
||||
|
||||
nightly:
|
||||
name: Rust nightly ${{matrix.os == 'windows' && '(windows)' || ''}}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "1.0.214"
|
||||
version = "1.0.217"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
build = "build.rs"
|
||||
categories = ["encoding", "no-std", "no-std::no-alloc"]
|
||||
@@ -37,7 +37,7 @@ rustdoc-args = ["--generate-link-to-definition"]
|
||||
# is compatible with exactly one serde release because the generated code
|
||||
# involves nonpublic APIs which are not bound by semver.
|
||||
[target.'cfg(any())'.dependencies]
|
||||
serde_derive = { version = "=1.0.214", path = "../serde_derive" }
|
||||
serde_derive = { version = "=1.0.217", path = "../serde_derive" }
|
||||
|
||||
|
||||
### FEATURES #################################################################
|
||||
|
||||
+5
-23
@@ -1,6 +1,6 @@
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::str::{self, FromStr};
|
||||
use std::str;
|
||||
|
||||
// The rustc-cfg strings below are *not* public API. Please let us know by
|
||||
// opening a GitHub issue if your build environment requires some way to enable
|
||||
@@ -108,30 +108,12 @@ fn main() {
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
let rustc = match env::var_os("RUSTC") {
|
||||
Some(rustc) => rustc,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let output = match Command::new(rustc).arg("--version").output() {
|
||||
Ok(output) => output,
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
let version = match str::from_utf8(&output.stdout) {
|
||||
Ok(version) => version,
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
let rustc = env::var_os("RUSTC")?;
|
||||
let output = Command::new(rustc).arg("--version").output().ok()?;
|
||||
let version = str::from_utf8(&output.stdout).ok()?;
|
||||
let mut pieces = version.split('.');
|
||||
if pieces.next() != Some("rustc 1") {
|
||||
return None;
|
||||
}
|
||||
|
||||
let next = match pieces.next() {
|
||||
Some(next) => next,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
u32::from_str(next).ok()
|
||||
pieces.next()?.parse().ok()
|
||||
}
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Serde types in rustdoc of other crates get linked to here.
|
||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.214")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.217")]
|
||||
// Support using Serde without the standard library!
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
// Show which crate feature enables conditionally compiled APIs in documentation.
|
||||
|
||||
@@ -54,6 +54,7 @@ enum Unsupported {
|
||||
Sequence,
|
||||
Tuple,
|
||||
TupleStruct,
|
||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||
Enum,
|
||||
}
|
||||
|
||||
@@ -70,6 +71,7 @@ impl Display for Unsupported {
|
||||
Unsupported::Sequence => formatter.write_str("a sequence"),
|
||||
Unsupported::Tuple => formatter.write_str("a tuple"),
|
||||
Unsupported::TupleStruct => formatter.write_str("a tuple struct"),
|
||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||
Unsupported::Enum => formatter.write_str("an enum"),
|
||||
}
|
||||
}
|
||||
@@ -1095,9 +1097,9 @@ where
|
||||
self,
|
||||
_: &'static str,
|
||||
_: u32,
|
||||
_: &'static str,
|
||||
variant: &'static str,
|
||||
) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Self::bad_type(Unsupported::Enum))
|
||||
self.0.serialize_entry(variant, &())
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T>(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_derive"
|
||||
version = "1.0.214"
|
||||
version = "1.0.217"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
categories = ["no-std", "no-std::no-alloc"]
|
||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||
|
||||
+31
-8
@@ -1,5 +1,6 @@
|
||||
use crate::fragment::{Expr, Fragment, Match, Stmts};
|
||||
use crate::internals::ast::{Container, Data, Field, Style, Variant};
|
||||
use crate::internals::name::Name;
|
||||
use crate::internals::{attr, replace_receiver, ungroup, Ctxt, Derive};
|
||||
use crate::{bound, dummy, pretend, this};
|
||||
use proc_macro2::{Literal, Span, TokenStream};
|
||||
@@ -32,6 +33,7 @@ pub fn expand_derive_deserialize(input: &mut syn::DeriveInput) -> syn::Result<To
|
||||
let vis = &input.vis;
|
||||
let used = pretend::pretend_used(&cont, params.is_packed);
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics #ident #ty_generics #where_clause {
|
||||
#vis fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<#remote #ty_generics, __D::Error>
|
||||
where
|
||||
@@ -423,6 +425,7 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||
type Value = #this_type #ty_generics;
|
||||
|
||||
@@ -558,6 +561,7 @@ fn deserialize_tuple(
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||
type Value = #this_type #ty_generics;
|
||||
|
||||
@@ -657,6 +661,7 @@ fn deserialize_tuple_in_place(
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause {
|
||||
type Value = ();
|
||||
|
||||
@@ -1019,6 +1024,7 @@ fn deserialize_struct(
|
||||
|
||||
let visitor_seed = match form {
|
||||
StructForm::ExternallyTagged(..) if has_flatten => Some(quote! {
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||
type Value = #this_type #ty_generics;
|
||||
|
||||
@@ -1083,6 +1089,7 @@ fn deserialize_struct(
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||
type Value = #this_type #ty_generics;
|
||||
|
||||
@@ -1164,6 +1171,7 @@ fn deserialize_struct_in_place(
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause {
|
||||
type Value = ();
|
||||
|
||||
@@ -1337,6 +1345,7 @@ fn deserialize_externally_tagged_enum(
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||
type Value = #this_type #ty_generics;
|
||||
|
||||
@@ -1598,6 +1607,7 @@ fn deserialize_adjacently_tagged_enum(
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause {
|
||||
type Value = #this_type #ty_generics;
|
||||
|
||||
@@ -1617,6 +1627,7 @@ fn deserialize_adjacently_tagged_enum(
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||
type Value = #this_type #ty_generics;
|
||||
|
||||
@@ -2002,7 +2013,7 @@ fn deserialize_untagged_newtype_variant(
|
||||
|
||||
struct FieldWithAliases<'a> {
|
||||
ident: Ident,
|
||||
aliases: &'a BTreeSet<String>,
|
||||
aliases: &'a BTreeSet<Name>,
|
||||
}
|
||||
|
||||
fn deserialize_generated_identifier(
|
||||
@@ -2045,12 +2056,14 @@ fn deserialize_generated_identifier(
|
||||
#[doc(hidden)]
|
||||
struct __FieldVisitor;
|
||||
|
||||
#[automatically_derived]
|
||||
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
|
||||
type Value = __Field #lifetime;
|
||||
|
||||
#visitor_impl
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl<'de> _serde::Deserialize<'de> for __Field #lifetime {
|
||||
#[inline]
|
||||
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
@@ -2189,6 +2202,7 @@ fn deserialize_custom_identifier(
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause {
|
||||
type Value = #this_type #ty_generics;
|
||||
|
||||
@@ -2216,7 +2230,11 @@ fn deserialize_identifier(
|
||||
let ident = &field.ident;
|
||||
let aliases = field.aliases;
|
||||
// `aliases` also contains a main name
|
||||
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
|
||||
quote! {
|
||||
#(
|
||||
#aliases => _serde::__private::Ok(#this_value::#ident),
|
||||
)*
|
||||
}
|
||||
});
|
||||
let bytes_mapping = deserialized_fields.iter().map(|field| {
|
||||
let ident = &field.ident;
|
||||
@@ -2224,8 +2242,12 @@ fn deserialize_identifier(
|
||||
let aliases = field
|
||||
.aliases
|
||||
.iter()
|
||||
.map(|alias| Literal::byte_string(alias.as_bytes()));
|
||||
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
|
||||
.map(|alias| Literal::byte_string(alias.value.as_bytes()));
|
||||
quote! {
|
||||
#(
|
||||
#aliases => _serde::__private::Ok(#this_value::#ident),
|
||||
)*
|
||||
}
|
||||
});
|
||||
|
||||
let expecting = expecting.unwrap_or(if is_variant {
|
||||
@@ -2423,7 +2445,7 @@ fn deserialize_identifier(
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
#(#str_mapping,)*
|
||||
#(#str_mapping)*
|
||||
_ => {
|
||||
#value_as_borrowed_str_content
|
||||
#fallthrough_borrowed_arm
|
||||
@@ -2436,7 +2458,7 @@ fn deserialize_identifier(
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
#(#bytes_mapping,)*
|
||||
#(#bytes_mapping)*
|
||||
_ => {
|
||||
#bytes_to_str
|
||||
#value_as_borrowed_bytes_content
|
||||
@@ -2461,7 +2483,7 @@ fn deserialize_identifier(
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
#(#str_mapping,)*
|
||||
#(#str_mapping)*
|
||||
_ => {
|
||||
#value_as_str_content
|
||||
#fallthrough_arm
|
||||
@@ -2474,7 +2496,7 @@ fn deserialize_identifier(
|
||||
__E: _serde::de::Error,
|
||||
{
|
||||
match __value {
|
||||
#(#bytes_mapping,)*
|
||||
#(#bytes_mapping)*
|
||||
_ => {
|
||||
#bytes_to_str
|
||||
#value_as_bytes_content
|
||||
@@ -2900,6 +2922,7 @@ fn wrap_deserialize_with(
|
||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause {
|
||||
fn deserialize<__D>(#deserializer_var: __D) -> _serde::__private::Result<Self, __D::Error>
|
||||
where
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::internals::name::{MultiName, Name};
|
||||
use crate::internals::symbol::*;
|
||||
use crate::internals::{ungroup, Ctxt};
|
||||
use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
|
||||
@@ -21,7 +22,7 @@ use syn::{parse_quote, token, Ident, Lifetime, Token};
|
||||
|
||||
pub use crate::internals::case::RenameRule;
|
||||
|
||||
struct Attr<'c, T> {
|
||||
pub(crate) struct Attr<'c, T> {
|
||||
cx: &'c Ctxt,
|
||||
name: Symbol,
|
||||
tokens: TokenStream,
|
||||
@@ -62,7 +63,7 @@ impl<'c, T> Attr<'c, T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get(self) -> Option<T> {
|
||||
pub(crate) fn get(self) -> Option<T> {
|
||||
self.value
|
||||
}
|
||||
|
||||
@@ -90,7 +91,7 @@ impl<'c> BoolAttr<'c> {
|
||||
}
|
||||
}
|
||||
|
||||
struct VecAttr<'c, T> {
|
||||
pub(crate) struct VecAttr<'c, T> {
|
||||
cx: &'c Ctxt,
|
||||
name: Symbol,
|
||||
first_dup_tokens: TokenStream,
|
||||
@@ -125,63 +126,13 @@ impl<'c, T> VecAttr<'c, T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn get(self) -> Vec<T> {
|
||||
pub(crate) fn get(self) -> Vec<T> {
|
||||
self.values
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Name {
|
||||
serialize: String,
|
||||
serialize_renamed: bool,
|
||||
deserialize: String,
|
||||
deserialize_renamed: bool,
|
||||
deserialize_aliases: BTreeSet<String>,
|
||||
}
|
||||
|
||||
fn unraw(ident: &Ident) -> String {
|
||||
ident.to_string().trim_start_matches("r#").to_owned()
|
||||
}
|
||||
|
||||
impl Name {
|
||||
fn from_attrs(
|
||||
source_name: String,
|
||||
ser_name: Attr<String>,
|
||||
de_name: Attr<String>,
|
||||
de_aliases: Option<VecAttr<String>>,
|
||||
) -> Name {
|
||||
let mut alias_set = BTreeSet::new();
|
||||
if let Some(de_aliases) = de_aliases {
|
||||
for alias_name in de_aliases.get() {
|
||||
alias_set.insert(alias_name);
|
||||
}
|
||||
}
|
||||
|
||||
let ser_name = ser_name.get();
|
||||
let ser_renamed = ser_name.is_some();
|
||||
let de_name = de_name.get();
|
||||
let de_renamed = de_name.is_some();
|
||||
Name {
|
||||
serialize: ser_name.unwrap_or_else(|| source_name.clone()),
|
||||
serialize_renamed: ser_renamed,
|
||||
deserialize: de_name.unwrap_or(source_name),
|
||||
deserialize_renamed: de_renamed,
|
||||
deserialize_aliases: alias_set,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the container name for the container when serializing.
|
||||
pub fn serialize_name(&self) -> &str {
|
||||
&self.serialize
|
||||
}
|
||||
|
||||
/// Return the container name for the container when deserializing.
|
||||
pub fn deserialize_name(&self) -> &str {
|
||||
&self.deserialize
|
||||
}
|
||||
|
||||
fn deserialize_aliases(&self) -> &BTreeSet<String> {
|
||||
&self.deserialize_aliases
|
||||
}
|
||||
fn unraw(ident: &Ident) -> Ident {
|
||||
Ident::new(ident.to_string().trim_start_matches("r#"), ident.span())
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@@ -203,7 +154,7 @@ impl RenameAllRules {
|
||||
|
||||
/// Represents struct or enum attribute information.
|
||||
pub struct Container {
|
||||
name: Name,
|
||||
name: MultiName,
|
||||
transparent: bool,
|
||||
deny_unknown_fields: bool,
|
||||
default: Default,
|
||||
@@ -327,8 +278,8 @@ impl Container {
|
||||
// #[serde(rename = "foo")]
|
||||
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
|
||||
let (ser, de) = get_renames(cx, RENAME, &meta)?;
|
||||
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
|
||||
de_name.set_opt(&meta.path, de.as_ref().map(syn::LitStr::value));
|
||||
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
|
||||
de_name.set_opt(&meta.path, de.as_ref().map(Name::from));
|
||||
} else if meta.path == RENAME_ALL {
|
||||
// #[serde(rename_all = "foo")]
|
||||
// #[serde(rename_all(serialize = "foo", deserialize = "bar"))]
|
||||
@@ -567,7 +518,7 @@ impl Container {
|
||||
}
|
||||
|
||||
Container {
|
||||
name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None),
|
||||
name: MultiName::from_attrs(Name::from(&unraw(&item.ident)), ser_name, de_name, None),
|
||||
transparent: transparent.get(),
|
||||
deny_unknown_fields: deny_unknown_fields.get(),
|
||||
default: default.get().unwrap_or(Default::None),
|
||||
@@ -594,7 +545,7 @@ impl Container {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &Name {
|
||||
pub fn name(&self) -> &MultiName {
|
||||
&self.name
|
||||
}
|
||||
|
||||
@@ -781,7 +732,7 @@ fn decide_identifier(
|
||||
|
||||
/// Represents variant attribute information
|
||||
pub struct Variant {
|
||||
name: Name,
|
||||
name: MultiName,
|
||||
rename_all_rules: RenameAllRules,
|
||||
ser_bound: Option<Vec<syn::WherePredicate>>,
|
||||
de_bound: Option<Vec<syn::WherePredicate>>,
|
||||
@@ -832,15 +783,15 @@ impl Variant {
|
||||
// #[serde(rename = "foo")]
|
||||
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
|
||||
let (ser, de) = get_multiple_renames(cx, &meta)?;
|
||||
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
|
||||
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
|
||||
for de_value in de {
|
||||
de_name.set_if_none(de_value.value());
|
||||
de_aliases.insert(&meta.path, de_value.value());
|
||||
de_name.set_if_none(Name::from(&de_value));
|
||||
de_aliases.insert(&meta.path, Name::from(&de_value));
|
||||
}
|
||||
} else if meta.path == ALIAS {
|
||||
// #[serde(alias = "foo")]
|
||||
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
|
||||
de_aliases.insert(&meta.path, s.value());
|
||||
de_aliases.insert(&meta.path, Name::from(&s));
|
||||
}
|
||||
} else if meta.path == RENAME_ALL {
|
||||
// #[serde(rename_all = "foo")]
|
||||
@@ -947,7 +898,12 @@ impl Variant {
|
||||
}
|
||||
|
||||
Variant {
|
||||
name: Name::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)),
|
||||
name: MultiName::from_attrs(
|
||||
Name::from(&unraw(&variant.ident)),
|
||||
ser_name,
|
||||
de_name,
|
||||
Some(de_aliases),
|
||||
),
|
||||
rename_all_rules: RenameAllRules {
|
||||
serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
|
||||
deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
|
||||
@@ -964,20 +920,23 @@ impl Variant {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &Name {
|
||||
pub fn name(&self) -> &MultiName {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn aliases(&self) -> &BTreeSet<String> {
|
||||
pub fn aliases(&self) -> &BTreeSet<Name> {
|
||||
self.name.deserialize_aliases()
|
||||
}
|
||||
|
||||
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
|
||||
if !self.name.serialize_renamed {
|
||||
self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize);
|
||||
self.name.serialize.value =
|
||||
rules.serialize.apply_to_variant(&self.name.serialize.value);
|
||||
}
|
||||
if !self.name.deserialize_renamed {
|
||||
self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
|
||||
self.name.deserialize.value = rules
|
||||
.deserialize
|
||||
.apply_to_variant(&self.name.deserialize.value);
|
||||
}
|
||||
self.name
|
||||
.deserialize_aliases
|
||||
@@ -1023,7 +982,7 @@ impl Variant {
|
||||
|
||||
/// Represents field attribute information
|
||||
pub struct Field {
|
||||
name: Name,
|
||||
name: MultiName,
|
||||
skip_serializing: bool,
|
||||
skip_deserializing: bool,
|
||||
skip_serializing_if: Option<syn::ExprPath>,
|
||||
@@ -1082,8 +1041,11 @@ impl Field {
|
||||
let mut flatten = BoolAttr::none(cx, FLATTEN);
|
||||
|
||||
let ident = match &field.ident {
|
||||
Some(ident) => unraw(ident),
|
||||
None => index.to_string(),
|
||||
Some(ident) => Name::from(&unraw(ident)),
|
||||
None => Name {
|
||||
value: index.to_string(),
|
||||
span: Span::call_site(),
|
||||
},
|
||||
};
|
||||
|
||||
if let Some(borrow_attribute) = attrs.and_then(|variant| variant.borrow.as_ref()) {
|
||||
@@ -1119,15 +1081,15 @@ impl Field {
|
||||
// #[serde(rename = "foo")]
|
||||
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
|
||||
let (ser, de) = get_multiple_renames(cx, &meta)?;
|
||||
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
|
||||
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
|
||||
for de_value in de {
|
||||
de_name.set_if_none(de_value.value());
|
||||
de_aliases.insert(&meta.path, de_value.value());
|
||||
de_name.set_if_none(Name::from(&de_value));
|
||||
de_aliases.insert(&meta.path, Name::from(&de_value));
|
||||
}
|
||||
} else if meta.path == ALIAS {
|
||||
// #[serde(alias = "foo")]
|
||||
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
|
||||
de_aliases.insert(&meta.path, s.value());
|
||||
de_aliases.insert(&meta.path, Name::from(&s));
|
||||
}
|
||||
} else if meta.path == DEFAULT {
|
||||
if meta.input.peek(Token![=]) {
|
||||
@@ -1290,7 +1252,7 @@ impl Field {
|
||||
}
|
||||
|
||||
Field {
|
||||
name: Name::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
|
||||
name: MultiName::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
|
||||
skip_serializing: skip_serializing.get(),
|
||||
skip_deserializing: skip_deserializing.get(),
|
||||
skip_serializing_if: skip_serializing_if.get(),
|
||||
@@ -1306,20 +1268,22 @@ impl Field {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &Name {
|
||||
pub fn name(&self) -> &MultiName {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn aliases(&self) -> &BTreeSet<String> {
|
||||
pub fn aliases(&self) -> &BTreeSet<Name> {
|
||||
self.name.deserialize_aliases()
|
||||
}
|
||||
|
||||
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
|
||||
if !self.name.serialize_renamed {
|
||||
self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize);
|
||||
self.name.serialize.value = rules.serialize.apply_to_field(&self.name.serialize.value);
|
||||
}
|
||||
if !self.name.deserialize_renamed {
|
||||
self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
|
||||
self.name.deserialize.value = rules
|
||||
.deserialize
|
||||
.apply_to_field(&self.name.deserialize.value);
|
||||
}
|
||||
self.name
|
||||
.deserialize_aliases
|
||||
@@ -1769,7 +1733,7 @@ fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool {
|
||||
// attribute on the field so there must be at least one borrowable lifetime.
|
||||
fn borrowable_lifetimes(
|
||||
cx: &Ctxt,
|
||||
name: &str,
|
||||
name: &Name,
|
||||
field: &syn::Field,
|
||||
) -> Result<BTreeSet<syn::Lifetime>, ()> {
|
||||
let mut lifetimes = BTreeSet::new();
|
||||
|
||||
@@ -329,13 +329,13 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
|
||||
let name = field.attrs.name();
|
||||
let ser_name = name.serialize_name();
|
||||
|
||||
if check_ser && ser_name == tag {
|
||||
if check_ser && ser_name.value == tag {
|
||||
diagnose_conflict();
|
||||
return;
|
||||
}
|
||||
|
||||
for de_name in field.attrs.aliases() {
|
||||
if check_de && de_name == tag {
|
||||
if check_de && de_name.value == tag {
|
||||
diagnose_conflict();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod ast;
|
||||
pub mod attr;
|
||||
pub mod name;
|
||||
|
||||
mod case;
|
||||
mod check;
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
use crate::internals::attr::{Attr, VecAttr};
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::ToTokens;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt::{self, Display};
|
||||
use syn::LitStr;
|
||||
|
||||
pub struct MultiName {
|
||||
pub(crate) serialize: Name,
|
||||
pub(crate) serialize_renamed: bool,
|
||||
pub(crate) deserialize: Name,
|
||||
pub(crate) deserialize_renamed: bool,
|
||||
pub(crate) deserialize_aliases: BTreeSet<Name>,
|
||||
}
|
||||
|
||||
impl MultiName {
|
||||
pub(crate) fn from_attrs(
|
||||
source_name: Name,
|
||||
ser_name: Attr<Name>,
|
||||
de_name: Attr<Name>,
|
||||
de_aliases: Option<VecAttr<Name>>,
|
||||
) -> Self {
|
||||
let mut alias_set = BTreeSet::new();
|
||||
if let Some(de_aliases) = de_aliases {
|
||||
for alias_name in de_aliases.get() {
|
||||
alias_set.insert(alias_name);
|
||||
}
|
||||
}
|
||||
|
||||
let ser_name = ser_name.get();
|
||||
let ser_renamed = ser_name.is_some();
|
||||
let de_name = de_name.get();
|
||||
let de_renamed = de_name.is_some();
|
||||
MultiName {
|
||||
serialize: ser_name.unwrap_or_else(|| source_name.clone()),
|
||||
serialize_renamed: ser_renamed,
|
||||
deserialize: de_name.unwrap_or(source_name),
|
||||
deserialize_renamed: de_renamed,
|
||||
deserialize_aliases: alias_set,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the container name for the container when serializing.
|
||||
pub fn serialize_name(&self) -> &Name {
|
||||
&self.serialize
|
||||
}
|
||||
|
||||
/// Return the container name for the container when deserializing.
|
||||
pub fn deserialize_name(&self) -> &Name {
|
||||
&self.deserialize
|
||||
}
|
||||
|
||||
pub(crate) fn deserialize_aliases(&self) -> &BTreeSet<Name> {
|
||||
&self.deserialize_aliases
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Name {
|
||||
pub value: String,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl ToTokens for Name {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
LitStr::new(&self.value, self.span).to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Name {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
Ord::cmp(&self.value, &other.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Name {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(Ord::cmp(self, other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Name {}
|
||||
|
||||
impl PartialEq for Name {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.value == other.value
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Ident> for Name {
|
||||
fn from(ident: &Ident) -> Self {
|
||||
Name {
|
||||
value: ident.to_string(),
|
||||
span: ident.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&LitStr> for Name {
|
||||
fn from(lit: &LitStr) -> Self {
|
||||
Name {
|
||||
value: lit.value(),
|
||||
span: lit.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Name {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&self.value, formatter)
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
//!
|
||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.214")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.217")]
|
||||
#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
|
||||
// Ignored clippy lints
|
||||
#![allow(
|
||||
|
||||
+11
-6
@@ -1,5 +1,6 @@
|
||||
use crate::fragment::{Fragment, Match, Stmts};
|
||||
use crate::internals::ast::{Container, Data, Field, Style, Variant};
|
||||
use crate::internals::name::Name;
|
||||
use crate::internals::{attr, replace_receiver, Ctxt, Derive};
|
||||
use crate::{bound, dummy, pretend, this};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
@@ -28,6 +29,7 @@ pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result<Toke
|
||||
let vis = &input.vis;
|
||||
let used = pretend::pretend_used(&cont, params.is_packed);
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
impl #impl_generics #ident #ty_generics #where_clause {
|
||||
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
@@ -732,6 +734,7 @@ fn serialize_adjacently_tagged_variant(
|
||||
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
|
||||
fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
@@ -798,9 +801,9 @@ fn serialize_untagged_variant(
|
||||
|
||||
enum TupleVariant<'a> {
|
||||
ExternallyTagged {
|
||||
type_name: &'a str,
|
||||
type_name: &'a Name,
|
||||
variant_index: u32,
|
||||
variant_name: &'a str,
|
||||
variant_name: &'a Name,
|
||||
},
|
||||
Untagged,
|
||||
}
|
||||
@@ -867,11 +870,11 @@ fn serialize_tuple_variant(
|
||||
enum StructVariant<'a> {
|
||||
ExternallyTagged {
|
||||
variant_index: u32,
|
||||
variant_name: &'a str,
|
||||
variant_name: &'a Name,
|
||||
},
|
||||
InternallyTagged {
|
||||
tag: &'a str,
|
||||
variant_name: &'a str,
|
||||
variant_name: &'a Name,
|
||||
},
|
||||
Untagged,
|
||||
}
|
||||
@@ -880,7 +883,7 @@ fn serialize_struct_variant(
|
||||
context: StructVariant,
|
||||
params: &Parameters,
|
||||
fields: &[Field],
|
||||
name: &str,
|
||||
name: &Name,
|
||||
) -> Fragment {
|
||||
if fields.iter().any(|field| field.attrs.flatten()) {
|
||||
return serialize_struct_variant_with_flatten(context, params, fields, name);
|
||||
@@ -964,7 +967,7 @@ fn serialize_struct_variant_with_flatten(
|
||||
context: StructVariant,
|
||||
params: &Parameters,
|
||||
fields: &[Field],
|
||||
name: &str,
|
||||
name: &Name,
|
||||
) -> Fragment {
|
||||
let struct_trait = StructTrait::SerializeMap;
|
||||
let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);
|
||||
@@ -996,6 +999,7 @@ fn serialize_struct_variant_with_flatten(
|
||||
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
|
||||
fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
@@ -1238,6 +1242,7 @@ fn wrap_serialize_with(
|
||||
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||
}
|
||||
|
||||
#[automatically_derived]
|
||||
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
|
||||
fn serialize<__S>(&#self_var, #serializer_var: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
|
||||
where
|
||||
|
||||
@@ -13,7 +13,7 @@ serde = { path = "../serde" }
|
||||
|
||||
[dev-dependencies]
|
||||
automod = "1.0.1"
|
||||
fnv = "1.0"
|
||||
foldhash = "0.1"
|
||||
rustversion = "1.0"
|
||||
serde = { path = "../serde", features = ["rc"] }
|
||||
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
|
||||
|
||||
@@ -10,4 +10,10 @@ libc = { version = "0.2", default-features = false }
|
||||
serde = { path = "../../serde", default-features = false }
|
||||
serde_derive = { path = "../../serde_derive" }
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
|
||||
[workspace]
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
#![allow(internal_features)]
|
||||
#![feature(lang_items, start)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[start]
|
||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
use core::ffi::c_int;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(_argc: c_int, _argv: *const *const u8) -> c_int {
|
||||
0
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_eh_personality() {}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
unsafe {
|
||||
|
||||
@@ -34,9 +34,8 @@ macro_rules! hashset {
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}};
|
||||
($hasher:ident @ $($value:expr),+) => {{
|
||||
use std::hash::BuildHasherDefault;
|
||||
let mut set = HashSet::with_hasher(BuildHasherDefault::<$hasher>::default());
|
||||
($hasher:ty; $($value:expr),+) => {{
|
||||
let mut set = HashSet::<_, $hasher>::default();
|
||||
$(set.insert($value);)+
|
||||
set
|
||||
}};
|
||||
@@ -51,9 +50,8 @@ macro_rules! hashmap {
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}};
|
||||
($hasher:ident @ $($key:expr => $value:expr),+) => {{
|
||||
use std::hash::BuildHasherDefault;
|
||||
let mut map = HashMap::with_hasher(BuildHasherDefault::<$hasher>::default());
|
||||
($hasher:ty; $($key:expr => $value:expr),+) => {{
|
||||
let mut map = HashMap::<_, _, $hasher>::default();
|
||||
$(map.insert($key, $value);)+
|
||||
map
|
||||
}};
|
||||
|
||||
@@ -2655,11 +2655,46 @@ mod flatten {
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
enum Enum {
|
||||
Unit,
|
||||
Newtype(HashMap<String, String>),
|
||||
Tuple(u32, u32),
|
||||
Struct { index: u32, value: u32 },
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit() {
|
||||
let value = Flatten {
|
||||
data: Enum::Unit,
|
||||
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
|
||||
};
|
||||
assert_tokens(
|
||||
&value,
|
||||
&[
|
||||
Token::Map { len: None },
|
||||
// data
|
||||
Token::Str("Unit"), // variant
|
||||
Token::Unit,
|
||||
// extra
|
||||
Token::Str("extra_key"),
|
||||
Token::Str("extra value"),
|
||||
Token::MapEnd,
|
||||
],
|
||||
);
|
||||
assert_de_tokens(
|
||||
&value,
|
||||
&[
|
||||
Token::Map { len: None },
|
||||
// extra
|
||||
Token::Str("extra_key"),
|
||||
Token::Str("extra value"),
|
||||
// data
|
||||
Token::Str("Unit"), // variant
|
||||
Token::Unit,
|
||||
Token::MapEnd,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn newtype() {
|
||||
assert_tokens(
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
)]
|
||||
#![cfg_attr(feature = "unstable", feature(never_type))]
|
||||
|
||||
use fnv::FnvHasher;
|
||||
use serde::de::value::{F32Deserializer, F64Deserializer};
|
||||
use serde::de::{Deserialize, DeserializeOwned, Deserializer, IntoDeserializer};
|
||||
use serde_derive::Deserialize;
|
||||
@@ -1040,7 +1039,7 @@ fn test_hashset() {
|
||||
],
|
||||
);
|
||||
test(
|
||||
hashset![FnvHasher @ 1, 2, 3],
|
||||
hashset![foldhash::fast::FixedState; 1, 2, 3],
|
||||
&[
|
||||
Token::Seq { len: Some(3) },
|
||||
Token::I32(1),
|
||||
@@ -1275,7 +1274,7 @@ fn test_hashmap() {
|
||||
],
|
||||
);
|
||||
test(
|
||||
hashmap![FnvHasher @ 1 => 2, 3 => 4],
|
||||
hashmap![foldhash::fast::FixedState; 1 => 2, 3 => 4],
|
||||
&[
|
||||
Token::Map { len: Some(2) },
|
||||
Token::I32(1),
|
||||
|
||||
@@ -769,7 +769,7 @@ fn test_gen() {
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[repr(packed)]
|
||||
#[repr(C, packed)]
|
||||
#[allow(dead_code)]
|
||||
struct Packed {
|
||||
x: u8,
|
||||
@@ -915,14 +915,14 @@ where
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[repr(packed)]
|
||||
#[repr(C, packed)]
|
||||
pub struct RemotePacked {
|
||||
pub a: u16,
|
||||
pub b: u32,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[repr(packed)]
|
||||
#[repr(C, packed)]
|
||||
#[serde(remote = "RemotePacked")]
|
||||
pub struct RemotePackedDef {
|
||||
a: u16,
|
||||
@@ -933,14 +933,14 @@ impl Drop for RemotePackedDef {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
#[repr(C, packed)]
|
||||
pub struct RemotePackedNonCopy {
|
||||
pub a: u16,
|
||||
pub b: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[repr(packed)]
|
||||
#[repr(C, packed)]
|
||||
#[serde(remote = "RemotePackedNonCopy")]
|
||||
pub struct RemotePackedNonCopyDef {
|
||||
a: u16,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#![allow(clippy::derive_partial_eq_without_eq, clippy::unreadable_literal)]
|
||||
#![cfg_attr(feature = "unstable", feature(never_type))]
|
||||
|
||||
use fnv::FnvHasher;
|
||||
use serde_derive::Serialize;
|
||||
use serde_test::{assert_ser_tokens, assert_ser_tokens_error, Configure, Token};
|
||||
use std::cell::RefCell;
|
||||
@@ -220,7 +219,7 @@ fn test_hashset() {
|
||||
&[Token::Seq { len: Some(1) }, Token::I32(1), Token::SeqEnd],
|
||||
);
|
||||
assert_ser_tokens(
|
||||
&hashset![FnvHasher @ 1],
|
||||
&hashset![foldhash::fast::FixedState; 1],
|
||||
&[Token::Seq { len: Some(1) }, Token::I32(1), Token::SeqEnd],
|
||||
);
|
||||
}
|
||||
@@ -300,7 +299,7 @@ fn test_hashmap() {
|
||||
],
|
||||
);
|
||||
assert_ser_tokens(
|
||||
&hashmap![FnvHasher @ 1 => 2],
|
||||
&hashmap![foldhash::fast::FixedState; 1 => 2],
|
||||
&[
|
||||
Token::Map { len: Some(1) },
|
||||
Token::I32(1),
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
enum E {
|
||||
S1 {
|
||||
#[serde(alias = "a", alias = "b", alias = "c")]
|
||||
a: (),
|
||||
|
||||
// Warning on "c" and "b"
|
||||
#[serde(alias = "c")]
|
||||
b: (),
|
||||
|
||||
#[serde(skip_deserializing)]
|
||||
c: (),
|
||||
},
|
||||
|
||||
S2 {
|
||||
#[serde(alias = "b", alias = "c")]
|
||||
a: (),
|
||||
|
||||
// Warning on "c"
|
||||
#[serde(rename = "c")]
|
||||
b: (),
|
||||
},
|
||||
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
S3 {
|
||||
#[serde(alias = "B", alias = "c")]
|
||||
a: (),
|
||||
|
||||
// Warning on "b" because this collides with the "B" above after
|
||||
// applying rename rules
|
||||
b: (),
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
enum E1 {
|
||||
#[serde(alias = "a", alias = "b", alias = "c")]
|
||||
a,
|
||||
|
||||
// Warning on "c" and "b"
|
||||
#[serde(alias = "c")]
|
||||
b,
|
||||
|
||||
#[serde(skip_deserializing)]
|
||||
c,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
enum E2 {
|
||||
#[serde(alias = "b", alias = "c")]
|
||||
a,
|
||||
|
||||
// Warning on "c"
|
||||
#[serde(rename = "c")]
|
||||
b,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
enum E3 {
|
||||
#[serde(alias = "B", alias = "c")]
|
||||
a,
|
||||
|
||||
// Warning on "b" because this collides with the "B" above after applying
|
||||
// rename rules
|
||||
b,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
__FAIL__;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
error[E0425]: cannot find value `__FAIL__` in this scope
|
||||
--> tests/ui/conflict/alias-enum.rs:74:5
|
||||
|
|
||||
74 | __FAIL__;
|
||||
| ^^^^^^^^ not found in this scope
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias-enum.rs:13:9
|
||||
|
|
||||
8 | #[serde(alias = "a", alias = "b", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
13 | b: (),
|
||||
| ^ no value can reach this
|
||||
|
|
||||
= note: `#[warn(unreachable_patterns)]` on by default
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias-enum.rs:12:25
|
||||
|
|
||||
8 | #[serde(alias = "a", alias = "b", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
12 | #[serde(alias = "c")]
|
||||
| ^^^ no value can reach this
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias-enum.rs:24:26
|
||||
|
|
||||
20 | #[serde(alias = "b", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
24 | #[serde(rename = "c")]
|
||||
| ^^^ no value can reach this
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias-enum.rs:35:9
|
||||
|
|
||||
30 | #[serde(alias = "B", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
35 | b: (),
|
||||
| ^ no value can reach this
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias-enum.rs:46:5
|
||||
|
|
||||
41 | #[serde(alias = "a", alias = "b", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
46 | b,
|
||||
| ^ no value can reach this
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias-enum.rs:45:21
|
||||
|
|
||||
41 | #[serde(alias = "a", alias = "b", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
45 | #[serde(alias = "c")]
|
||||
| ^^^ no value can reach this
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias-enum.rs:58:22
|
||||
|
|
||||
54 | #[serde(alias = "b", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
58 | #[serde(rename = "c")]
|
||||
| ^^^ no value can reach this
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias-enum.rs:70:5
|
||||
|
|
||||
65 | #[serde(alias = "B", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
70 | b,
|
||||
| ^ no value can reach this
|
||||
@@ -0,0 +1,39 @@
|
||||
use serde_derive::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct S1 {
|
||||
#[serde(alias = "a", alias = "b", alias = "c")]
|
||||
a: (),
|
||||
|
||||
// Warning on "c" and "b"
|
||||
#[serde(alias = "c")]
|
||||
b: (),
|
||||
|
||||
#[serde(skip_deserializing)]
|
||||
c: (),
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct S2 {
|
||||
#[serde(alias = "b", alias = "c")]
|
||||
a: (),
|
||||
|
||||
// Warning on "c"
|
||||
#[serde(rename = "c")]
|
||||
b: (),
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
struct S3 {
|
||||
#[serde(alias = "B", alias = "c")]
|
||||
a: (),
|
||||
|
||||
// Warning on "b" because this collides with the "B" above after applying
|
||||
// rename rules
|
||||
b: (),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
__FAIL__;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
error[E0425]: cannot find value `__FAIL__` in this scope
|
||||
--> tests/ui/conflict/alias.rs:38:5
|
||||
|
|
||||
38 | __FAIL__;
|
||||
| ^^^^^^^^ not found in this scope
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias.rs:10:5
|
||||
|
|
||||
5 | #[serde(alias = "a", alias = "b", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
10 | b: (),
|
||||
| ^ no value can reach this
|
||||
|
|
||||
= note: `#[warn(unreachable_patterns)]` on by default
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias.rs:9:21
|
||||
|
|
||||
5 | #[serde(alias = "a", alias = "b", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
9 | #[serde(alias = "c")]
|
||||
| ^^^ no value can reach this
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias.rs:22:22
|
||||
|
|
||||
18 | #[serde(alias = "b", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
22 | #[serde(rename = "c")]
|
||||
| ^^^ no value can reach this
|
||||
|
||||
warning: unreachable pattern
|
||||
--> tests/ui/conflict/alias.rs:34:5
|
||||
|
|
||||
29 | #[serde(alias = "B", alias = "c")]
|
||||
| --- matches all the relevant values
|
||||
...
|
||||
34 | b: (),
|
||||
| ^ no value can reach this
|
||||
Reference in New Issue
Block a user