Skip to content

Commit 329b19b

Browse files
author
lif
committed
Support telling serde where it is, i.e. when re-exported as a transitive dependency.
Supported by the `serde()` annotation in derive macros, which otherwise will assume that serde is a direct crate dependency. When a macro emits a type that derives Serialize/Deserialize, the user of that macro would normally have to directly depend on serde themselves for the resulting expansion of those derive macros. This can be cumbersome when consuming serde transitively via some other crate (i.e. progenitor). https://github.com/serde-rs/serde/blob/5a8dcac2ed1407fab3f7fd23f2d56af42dcd448f/serde_derive/src/internals/attr.rs#L556-L561
1 parent 80d6d23 commit 329b19b

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

typify-impl/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ pub struct TypeSpaceSettings {
173173
type_mod: Option<String>,
174174
extra_derives: Vec<String>,
175175
struct_builder: bool,
176+
serde_crate_location: Option<String>,
176177
}
177178

178179
impl TypeSpaceSettings {
@@ -192,6 +193,11 @@ impl TypeSpaceSettings {
192193
self.struct_builder = struct_builder;
193194
self
194195
}
196+
197+
pub fn with_serde_crate_location(&mut self, crate_location: String) -> &mut Self {
198+
self.serde_crate_location = Some(crate_location);
199+
self
200+
}
195201
}
196202

197203
impl TypeSpace {

typify-impl/src/type_entry.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,9 @@ impl TypeEntry {
406406
if *deny_unknown_fields {
407407
serde_options.push(quote! { deny_unknown_fields });
408408
}
409+
if let Some(crate_loc) = &type_space.settings.serde_crate_location {
410+
serde_options.push(quote! { crate = #crate_loc });
411+
}
409412

410413
let serde = (!serde_options.is_empty()).then(|| {
411414
quote! { #[serde( #( #serde_options ),* )] }
@@ -581,6 +584,9 @@ impl TypeEntry {
581584
if *deny_unknown_fields {
582585
serde_options.push(quote! { deny_unknown_fields });
583586
}
587+
if let Some(crate_loc) = &type_space.settings.serde_crate_location {
588+
serde_options.push(quote! { crate = #crate_loc });
589+
}
584590
let serde =
585591
(!serde_options.is_empty()).then(|| quote! { #[serde( #( #serde_options ),* )] });
586592

@@ -1182,6 +1188,9 @@ mod tests {
11821188
type_entry::{TypeEntry, TypeEntryStruct},
11831189
TypeEntryDetails, TypeSpace,
11841190
};
1191+
use quote::quote;
1192+
use schema::Schema;
1193+
use schemars::JsonSchema;
11851194

11861195
#[test]
11871196
fn test_ident() {
@@ -1225,4 +1234,53 @@ mod tests {
12251234
let parameter = t.type_parameter_ident(&ts, Some("a"));
12261235
assert_eq!(parameter.to_string(), "& 'a SomeType");
12271236
}
1237+
1238+
#[test]
1239+
fn test_alternate_crate_location() {
1240+
#[allow(dead_code)]
1241+
#[derive(Schema, JsonSchema)]
1242+
struct MyStruct {
1243+
my_enum: MyEnum,
1244+
}
1245+
#[allow(dead_code)]
1246+
#[derive(Schema, JsonSchema)]
1247+
enum MyEnum {
1248+
A,
1249+
}
1250+
1251+
let (mut type_space, _) = crate::test_util::get_type::<MyStruct>();
1252+
type_space
1253+
.settings
1254+
.with_serde_crate_location("crate::serde_reexport".to_string());
1255+
let actual = type_space.to_stream();
1256+
let expected = quote! {
1257+
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
1258+
#[serde(crate = "crate::serde_reexport")]
1259+
pub enum MyEnum {
1260+
A,
1261+
}
1262+
impl ToString for MyEnum {
1263+
fn to_string(&self) -> String {
1264+
match *self {
1265+
Self::A => "A".to_string(),
1266+
}
1267+
}
1268+
}
1269+
impl std::str::FromStr for MyEnum {
1270+
type Err = &'static str;
1271+
fn from_str(value: &str) -> Result<Self, Self::Err> {
1272+
match value {
1273+
"A" => Ok(Self::A),
1274+
_ => Err("invalid value"),
1275+
}
1276+
}
1277+
}
1278+
#[derive(Clone, Debug, Deserialize, Serialize)]
1279+
#[serde(crate = "crate::serde_reexport")]
1280+
pub struct MyStruct {
1281+
pub my_enum: MyEnum,
1282+
}
1283+
};
1284+
assert_eq!(actual.to_string(), expected.to_string());
1285+
}
12281286
}

0 commit comments

Comments
 (0)