Skip to content

Commit

Permalink
Change serde_path to crate
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sgrif committed Mar 28, 2019
1 parent 0e6ce8f commit b4d8a55
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 12 deletions.
2 changes: 1 addition & 1 deletion serde_derive/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
15 changes: 11 additions & 4 deletions serde_derive/src/internals/attr.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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(
Expand Down
13 changes: 7 additions & 6 deletions serde_derive/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -40,18 +41,18 @@ 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
}
}
}
};

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) {
Expand Down
2 changes: 1 addition & 1 deletion test_suite/tests/test_serde_path.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit b4d8a55

Please sign in to comment.