Allow `#[serde(serde_path = "...")]` to override `extern crate serde`
This is intended to be used by other crates which provide their own proc
macros and use serde internally. Today there's no consistent way to put
`#[derive(Deserialize)]` on a struct that consistently works, since
crates may be using either `features = ["derive"]` or relying on
`serde_derive` separately.
Even if we assume that everyone is using `features = ["derive"]`,
without this commit, any crate which generates
`#[derive(serde::Deserialize)]` forces its consumers to put `serde` in
their `Cargo.toml`, even if they aren't otherwise using serde for
anything.
Examples of crates which suffer from this in the real world are
tower-web and swirl.
With this feature, it's expected that these crates would have `pub
extern crate serde;` in some accessible path, and add
`#[serde(serde_path = "that_crate::wherever::serde")]` anywhere they
place serde's derives. Those crates would also have to derive
`that_crate::whatever::serde::Deserialize`, or `use` the macros
explicitly beforehand.
The test for this is a little funky, as it's testing this in a way that
is not the intended use case, or even one we want to support. It has its
own module which re-exports all of serde, but defines its own
`Serialize` and `Deserialize` traits. We then test that we generated
impls for those traits, instead of serde's. The only other way to test
this would be to create a new test crate which does not depend on serde,
but instead depends on `serde_derive` and a third crate which publicly
re-exports serde. This feels like way too much overhead for a single
test case, hence the funky test given.
I didn't see anywhere in this repo to document this attribute, so I
assume the docs will have to be done as a separate PR to a separate
repo.
Fixes #1487
2019-03-18 16:06:56 -05:00
|
|
|
#[test]
|
|
|
|
fn test_gen_custom_serde() {
|
|
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
2019-03-28 12:42:50 -05:00
|
|
|
#[serde(crate = "fake_serde")]
|
Allow `#[serde(serde_path = "...")]` to override `extern crate serde`
This is intended to be used by other crates which provide their own proc
macros and use serde internally. Today there's no consistent way to put
`#[derive(Deserialize)]` on a struct that consistently works, since
crates may be using either `features = ["derive"]` or relying on
`serde_derive` separately.
Even if we assume that everyone is using `features = ["derive"]`,
without this commit, any crate which generates
`#[derive(serde::Deserialize)]` forces its consumers to put `serde` in
their `Cargo.toml`, even if they aren't otherwise using serde for
anything.
Examples of crates which suffer from this in the real world are
tower-web and swirl.
With this feature, it's expected that these crates would have `pub
extern crate serde;` in some accessible path, and add
`#[serde(serde_path = "that_crate::wherever::serde")]` anywhere they
place serde's derives. Those crates would also have to derive
`that_crate::whatever::serde::Deserialize`, or `use` the macros
explicitly beforehand.
The test for this is a little funky, as it's testing this in a way that
is not the intended use case, or even one we want to support. It has its
own module which re-exports all of serde, but defines its own
`Serialize` and `Deserialize` traits. We then test that we generated
impls for those traits, instead of serde's. The only other way to test
this would be to create a new test crate which does not depend on serde,
but instead depends on `serde_derive` and a third crate which publicly
re-exports serde. This feels like way too much overhead for a single
test case, hence the funky test given.
I didn't see anywhere in this repo to document this attribute, so I
assume the docs will have to be done as a separate PR to a separate
repo.
Fixes #1487
2019-03-18 16:06:56 -05:00
|
|
|
struct Foo;
|
|
|
|
|
|
|
|
// Would be overlapping if serde::Serialize were implemented
|
|
|
|
impl AssertNotSerdeSerialize for Foo {}
|
|
|
|
// Would be overlapping if serde::Deserialize were implemented
|
|
|
|
impl<'a> AssertNotSerdeDeserialize<'a> for Foo {}
|
|
|
|
|
|
|
|
fake_serde::assert::<Foo>();
|
|
|
|
}
|
|
|
|
|
|
|
|
mod fake_serde {
|
|
|
|
pub use serde::*;
|
|
|
|
|
|
|
|
pub fn assert<T>()
|
|
|
|
where
|
|
|
|
T: Serialize,
|
|
|
|
T: for<'a> Deserialize<'a>,
|
2019-04-03 11:34:53 -05:00
|
|
|
{
|
|
|
|
}
|
Allow `#[serde(serde_path = "...")]` to override `extern crate serde`
This is intended to be used by other crates which provide their own proc
macros and use serde internally. Today there's no consistent way to put
`#[derive(Deserialize)]` on a struct that consistently works, since
crates may be using either `features = ["derive"]` or relying on
`serde_derive` separately.
Even if we assume that everyone is using `features = ["derive"]`,
without this commit, any crate which generates
`#[derive(serde::Deserialize)]` forces its consumers to put `serde` in
their `Cargo.toml`, even if they aren't otherwise using serde for
anything.
Examples of crates which suffer from this in the real world are
tower-web and swirl.
With this feature, it's expected that these crates would have `pub
extern crate serde;` in some accessible path, and add
`#[serde(serde_path = "that_crate::wherever::serde")]` anywhere they
place serde's derives. Those crates would also have to derive
`that_crate::whatever::serde::Deserialize`, or `use` the macros
explicitly beforehand.
The test for this is a little funky, as it's testing this in a way that
is not the intended use case, or even one we want to support. It has its
own module which re-exports all of serde, but defines its own
`Serialize` and `Deserialize` traits. We then test that we generated
impls for those traits, instead of serde's. The only other way to test
this would be to create a new test crate which does not depend on serde,
but instead depends on `serde_derive` and a third crate which publicly
re-exports serde. This feels like way too much overhead for a single
test case, hence the funky test given.
I didn't see anywhere in this repo to document this attribute, so I
assume the docs will have to be done as a separate PR to a separate
repo.
Fixes #1487
2019-03-18 16:06:56 -05:00
|
|
|
|
|
|
|
pub trait Serialize {
|
|
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait Deserialize<'a>: Sized {
|
|
|
|
fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error>;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
trait AssertNotSerdeSerialize {}
|
|
|
|
|
|
|
|
impl<T: serde::Serialize> AssertNotSerdeSerialize for T {}
|
|
|
|
|
|
|
|
trait AssertNotSerdeDeserialize<'a> {}
|
|
|
|
|
|
|
|
impl<'a, T: serde::Deserialize<'a>> AssertNotSerdeDeserialize<'a> for T {}
|