Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 84 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions example-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ authors = ["Adam H. Leventhal <[email protected]>"]
edition = "2021"

[dependencies]
educe = "0.4.20"
serde = "1.0"
serde_json = "1.0.91"

Expand Down
1 change: 1 addition & 0 deletions example-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ authors = ["Adam H. Leventhal <[email protected]>"]
edition = "2021"

[dependencies]
educe = "0.4.20"
typify = { path = "../typify" }
serde = "1.0"
serde_json = "1.0"
1 change: 1 addition & 0 deletions typify-impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ thiserror = "1.0"
unicode-ident = "1.0.6"

[dev-dependencies]
educe = "0.4.20"
expectorate = "1.0"
paste = "1.0"
schema = "0.0.1"
Expand Down
21 changes: 15 additions & 6 deletions typify-impl/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,35 +551,44 @@ impl TypeSpace {

Some("uuid") => {
self.uses_uuid = true;
Ok((TypeEntry::new_builtin("uuid::Uuid", &["Display"]), metadata))
Ok((
TypeEntry::new_builtin("uuid::Uuid", &["Default", "Display"]),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default Uuid does not seem useful

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as noted in the commit 5fabb9b (#184), I am unsure about all of these

metadata,
))
}

Some("date") => {
self.uses_chrono = true;
Ok((
TypeEntry::new_builtin("chrono::Date<chrono::offset::Utc>", &["Display"]),
TypeEntry::new_builtin(
"chrono::Date<chrono::offset::Utc>",
&["Default", "Display"],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

),
metadata,
))
}

Some("date-time") => {
self.uses_chrono = true;
Ok((
TypeEntry::new_builtin("chrono::DateTime<chrono::offset::Utc>", &["Display"]),
TypeEntry::new_builtin(
"chrono::DateTime<chrono::offset::Utc>",
&["Default", "Display"],
),
metadata,
))
}

Some("ip") => Ok((
TypeEntry::new_builtin("std::net::IpAddr", &["Display"]),
TypeEntry::new_builtin("std::net::IpAddr", &["Default", "Display"]),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

metadata,
)),
Some("ipv4") => Ok((
TypeEntry::new_builtin("std::net::Ipv4Addr", &["Display"]),
TypeEntry::new_builtin("std::net::Ipv4Addr", &["Default", "Display"]),
metadata,
)),
Some("ipv6") => Ok((
TypeEntry::new_builtin("std::net::Ipv6Addr", &["Display"]),
TypeEntry::new_builtin("std::net::Ipv6Addr", &["Default", "Display"]),
metadata,
)),
Some(unhandled) => {
Expand Down
8 changes: 6 additions & 2 deletions typify-impl/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1605,8 +1605,10 @@ mod tests {
type_entry.output(&type_space, &mut output);
let actual = output.into_stream();
let expected = quote! {
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, educe::Educe)]
#[educe(Default)]
pub enum ResultX {
#[educe(Default)]
Ok(u32),
Err(String),
}
Expand All @@ -1632,8 +1634,10 @@ mod tests {
type_entry.output(&type_space, &mut output);
let actual = output.into_stream();
let expected = quote! {
#[derive(A, B, C, Clone, D, Debug, Deserialize, Serialize)]
#[derive(A, B, C, Clone, D, Debug, Deserialize, Serialize, educe::Educe)]
#[educe(Default)]
pub enum ResultX {
#[educe(Default)]
Ok(u32),
Err(String),
}
Expand Down
61 changes: 55 additions & 6 deletions typify-impl/src/type_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,22 @@ impl TypeEntry {

let type_name = format_ident!("{}", name);

let variants_decl = variants
.iter()
.map(|variant| output_variant(variant, type_space, output, name))
.collect::<Vec<_>>();
// The normal Default derive doesn't work with struct enum variants.
let mut variants_decl: Vec<TokenStream>;
if default.is_none() {
variants_decl = vec![quote! { #[educe(Default)] }];
variants_decl.append(
&mut variants
.iter()
.map(|variant| output_variant(variant, type_space, output, name))
.collect::<Vec<_>>(),
);
} else {
variants_decl = variants
.iter()
.map(|variant| output_variant(variant, type_space, output, name))
.collect::<Vec<_>>();
}

// It should not be possible to construct an untagged enum
// with more than one simple variants--it would not be usable.
Expand Down Expand Up @@ -580,6 +592,32 @@ impl TypeEntry {
}
});

/*
// if using `educe` crate isnt acceptable, we can manually build the default value
// here similar to what `educe` is doing behind the scenes.
let default_value: serde_json::Value;
let default_stream: TokenStream;
if default.is_none() {
default_value = variants[0].name.clone().into();
// now we need to generate a <default_value>, or <default_value>::default(),
// but with structs it is more complicated, and needs a dedicated function like
// `output_default`, similar to `output_value`.
let default_stream = ...
}
else {
default_value = default.clone().unwrap().0;
let default_stream = self.output_value(type_space, &default_value, &quote! {}).unwrap();
}

let default_impl = quote! {
impl Default for #type_name {
fn default() -> Self {
#default_stream
}
}
};
*/

let default_impl = default.as_ref().map(|value| {
let default_stream = self.output_value(type_space, &value.0, &quote! {}).unwrap();
quote! {
Expand Down Expand Up @@ -647,6 +685,11 @@ impl TypeEntry {
}
});

let mut educe: TokenStream = TokenStream::default();
if default.is_none() {
derive_set.insert("educe::Educe");
educe = quote! { #[educe(Default)] };
}
let derives = strings_to_derives(
derive_set,
&self.derives,
Expand All @@ -656,6 +699,7 @@ impl TypeEntry {
let item = quote! {
#doc
#[derive(#(#derives),*)]
#educe
#serde
pub enum #type_name {
#(#variants_decl)*
Expand All @@ -674,7 +718,7 @@ impl TypeEntry {
type_space: &TypeSpace,
output: &mut OutputSpace,
struct_details: &TypeEntryStruct,
derive_set: BTreeSet<&str>,
mut derive_set: BTreeSet<&str>,
) {
let TypeEntryStruct {
name,
Expand Down Expand Up @@ -752,7 +796,9 @@ impl TypeEntry {
}
});
});

if default.is_none() {
derive_set.insert("Default");
}
let derives = strings_to_derives(
derive_set,
&self.derives,
Expand Down Expand Up @@ -1013,6 +1059,9 @@ impl TypeEntry {
}
});

if default_impl.is_none() {
derive_set.insert("Default");
}
let derives = strings_to_derives(
derive_set,
&self.derives,
Expand Down
2 changes: 1 addition & 1 deletion typify-impl/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ fn value_for_external_enum(
VariantDetails::Simple => None,
VariantDetails::Item(type_id) => {
let item = value_for_item(type_space, var_value, type_id, scope);
Some(quote! { #scope #type_ident::#var_ident ( #item ) })
Some(quote! { #scope #type_ident::#var_ident ( #item ::default() ) })
}
VariantDetails::Tuple(types) => {
let tup = value_for_tuple(type_space, var_value, types, scope)?;
Expand Down
Loading