Change serde_path to crate

Also changed the generated code to have at least one thing refer to the
path directly, rather than via `use` -- This shows that the impl *can*
work without `use`, but doesn't actually do all the work to remove the
`use` lines unless we decide we need this feature to work on the 2015
edition
This commit is contained in:
Sean Griffin 2019-03-28 11:42:50 -06:00
parent 0e6ce8fa50
commit b4d8a55b2a
4 changed files with 20 additions and 12 deletions

View File

@ -60,7 +60,7 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream
}
};
Ok(dummy::wrap_in_const(cont.attrs.serde_path(), "DESERIALIZE", ident, impl_block))
Ok(dummy::wrap_in_const(cont.attrs.custom_serde_path(), "DESERIALIZE", ident, impl_block))
}
fn precondition(cx: &Ctxt, cont: &Container) {

View File

@ -1,6 +1,7 @@
use internals::Ctxt;
use proc_macro2::{Group, Span, TokenStream, TokenTree};
use quote::ToTokens;
use std::borrow::Cow;
use std::collections::BTreeSet;
use std::str::FromStr;
use syn;
@ -299,7 +300,7 @@ impl Container {
let mut remote = Attr::none(cx, "remote");
let mut field_identifier = BoolAttr::none(cx, "field_identifier");
let mut variant_identifier = BoolAttr::none(cx, "variant_identifier");
let mut serde_path = Attr::none(cx, "serde_path");
let mut serde_path = Attr::none(cx, "crate");
for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) {
for meta_item in meta_items {
@ -584,8 +585,8 @@ impl Container {
variant_identifier.set_true(word);
}
// Parse `#[serde(serde_path = "foo")]`
Meta(NameValue(ref m)) if m.ident == "serde_path" => {
// Parse `#[serde(crate = "foo")]`
Meta(NameValue(ref m)) if m.ident == "crate" => {
if let Ok(path) = parse_lit_into_path(cx, &m.ident, &m.lit) {
serde_path.set(&m.ident, path)
}
@ -682,9 +683,15 @@ impl Container {
self.has_flatten = true;
}
pub fn serde_path(&self) -> Option<&syn::Path> {
pub fn custom_serde_path(&self) -> Option<&syn::Path> {
self.serde_path.as_ref()
}
pub fn serde_path<'a>(&'a self) -> Cow<'a, syn::Path> {
self.custom_serde_path()
.map(Cow::Borrowed)
.unwrap_or_else(|| Cow::Owned(parse_quote!(_serde)))
}
}
fn decide_tag(

View File

@ -22,15 +22,16 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
let body = Stmts(serialize_body(&cont, &params));
let serde = cont.attrs.serde_path();
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
let used = pretend::pretend_used(&cont);
quote! {
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,
__S: #serde::Serializer,
{
#used
#body
@ -40,10 +41,10 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
} else {
quote! {
#[automatically_derived]
impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
impl #impl_generics #serde::Serialize for #ident #ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> #serde::export::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
__S: #serde::Serializer,
{
#body
}
@ -51,7 +52,7 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
}
};
Ok(dummy::wrap_in_const(cont.attrs.serde_path(), "SERIALIZE", ident, impl_block))
Ok(dummy::wrap_in_const(cont.attrs.custom_serde_path(), "SERIALIZE", ident, impl_block))
}
fn precondition(cx: &Ctxt, cont: &Container) {

View File

@ -1,7 +1,7 @@
#[test]
fn test_gen_custom_serde() {
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(serde_path = "fake_serde")]
#[serde(crate = "fake_serde")]
struct Foo;
// Would be overlapping if serde::Serialize were implemented