diff --git a/Cargo.toml b/Cargo.toml index 45748eb..99cb8a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bomboni" -version = "0.1.47" +version = "0.1.48" authors = ["Tin Rabzelj "] description = "Utility Library for Rust" repository = "https://github.com/tinrab/bomboni" @@ -38,9 +38,9 @@ tokio = ["bomboni_common/tokio"] tonic = ["bomboni_proto/tonic", "bomboni_request/tonic"] [dependencies] -bomboni_common = { path = "bomboni_common", version = "0.1.47" } +bomboni_common = { path = "bomboni_common", version = "0.1.48" } -bomboni_prost = { path = "bomboni_prost", version = "0.1.47", optional = true } -bomboni_proto = { path = "bomboni_proto", version = "0.1.47", optional = true } -bomboni_request = { path = "bomboni_request", version = "0.1.47", optional = true } -bomboni_template = { path = "bomboni_template", version = "0.1.47", optional = true } +bomboni_prost = { path = "bomboni_prost", version = "0.1.48", optional = true } +bomboni_proto = { path = "bomboni_proto", version = "0.1.48", optional = true } +bomboni_request = { path = "bomboni_request", version = "0.1.48", optional = true } +bomboni_template = { path = "bomboni_template", version = "0.1.48", optional = true } diff --git a/bomboni_common/Cargo.toml b/bomboni_common/Cargo.toml index 5f43ba7..e655d3e 100644 --- a/bomboni_common/Cargo.toml +++ b/bomboni_common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bomboni_common" -version = "0.1.47" +version = "0.1.48" authors = ["Tin Rabzelj "] description = "Common things for Bomboni library." repository = "https://github.com/tinrab/bomboni" diff --git a/bomboni_prost/Cargo.toml b/bomboni_prost/Cargo.toml index fc8ede6..0e27f95 100644 --- a/bomboni_prost/Cargo.toml +++ b/bomboni_prost/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bomboni_prost" -version = "0.1.47" +version = "0.1.48" authors = ["Tin Rabzelj "] description = "Utilities for working with prost. Part of Bomboni library." repository = "https://github.com/tinrab/bomboni" diff --git a/bomboni_proto/Cargo.toml b/bomboni_proto/Cargo.toml index 2b54798..e5d4eb9 100644 --- a/bomboni_proto/Cargo.toml +++ b/bomboni_proto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bomboni_proto" -version = "0.1.47" +version = "0.1.48" authors = ["Tin Rabzelj "] description = "Utilities for working with Protobuf/gRPC. Part of Bomboni library." repository = "https://github.com/tinrab/bomboni" @@ -36,5 +36,5 @@ serde_json = { version = "1.0.108", optional = true } serde_json = "1.0.108" [build-dependencies] -bomboni_prost = { path = "../bomboni_prost", version = "0.1.47" } +bomboni_prost = { path = "../bomboni_prost", version = "0.1.48" } prost-build = "0.12.3" diff --git a/bomboni_request/Cargo.toml b/bomboni_request/Cargo.toml index 21c2704..f7e6812 100644 --- a/bomboni_request/Cargo.toml +++ b/bomboni_request/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bomboni_request" -version = "0.1.47" +version = "0.1.48" authors = ["Tin Rabzelj "] description = "Utilities for working with API requests. Part of Bomboni library." repository = "https://github.com/tinrab/bomboni" @@ -19,8 +19,8 @@ testing = [] tonic = ["bomboni_proto/tonic", "dep:tonic"] [dependencies] -bomboni_common = { path = "../bomboni_common", version = "0.1.47" } -bomboni_proto = { path = "../bomboni_proto", version = "0.1.47" } +bomboni_common = { path = "../bomboni_common", version = "0.1.48" } +bomboni_proto = { path = "../bomboni_proto", version = "0.1.48" } thiserror = "1.0.51" itertools = "0.12.0" time = { version = "0.3.31", features = ["formatting", "parsing"] } @@ -35,7 +35,7 @@ rand = "0.8.5" regex = "1.10.2" tonic = { version = "0.10.2", optional = true } -bomboni_request_derive = { path = "../bomboni_request_derive", version = "0.1.47", optional = true } +bomboni_request_derive = { path = "../bomboni_request_derive", version = "0.1.48", optional = true } [dev-dependencies] serde = { version = "1.0.193", features = ["derive"] } diff --git a/bomboni_request/src/parse/mod.rs b/bomboni_request/src/parse/mod.rs index 4f4e784..f11e100 100644 --- a/bomboni_request/src/parse/mod.rs +++ b/bomboni_request/src/parse/mod.rs @@ -134,7 +134,7 @@ mod tests { required_string_optional: String, nested: ParsedNestedItem, optional_nested: Option, - #[parse(default = NestedItem::default())] + #[parse(default = ParsedNestedItem::default())] default_nested: ParsedNestedItem, #[parse(default)] default_default_nested: ParsedNestedItem, @@ -1878,4 +1878,58 @@ mod tests { ) )); } + + #[test] + fn custom_default_field() { + #[derive(Debug, Clone, PartialEq, Default)] + struct Item { + part: Option, + } + + #[derive(Debug, Clone, PartialEq, Default)] + struct Part { + value: i32, + } + + #[derive(Debug, Clone, PartialEq, Parse)] + #[parse(source = Item, write)] + struct ParsedItem { + #[parse(default = get_default_part())] + part: ParsedPart, + } + + #[derive(Debug, Clone, PartialEq, Parse)] + #[parse(source = Part, write)] + struct ParsedPart { + value: i32, + } + + fn get_default_part() -> ParsedPart { + ParsedPart { value: 42 } + } + + assert_eq!( + ParsedItem::parse(Item { + part: Some(Part { value: 1337 }), + }) + .unwrap(), + ParsedItem { + part: ParsedPart { value: 1337 }, + } + ); + assert_eq!( + ParsedItem::parse(Item { part: None }).unwrap(), + ParsedItem { + part: ParsedPart { value: 42 }, + } + ); + assert_eq!( + Item::from(ParsedItem { + part: ParsedPart { value: 1337 }, + }), + Item { + part: Some(Part { value: 1337 }), + } + ); + } } diff --git a/bomboni_request_derive/Cargo.toml b/bomboni_request_derive/Cargo.toml index 7eaa514..2cd52a2 100644 --- a/bomboni_request_derive/Cargo.toml +++ b/bomboni_request_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bomboni_request_derive" -version = "0.1.47" +version = "0.1.48" authors = ["Tin Rabzelj "] description = "Provides derive implementations for Bomboni library." repository = "https://github.com/tinrab/bomboni" diff --git a/bomboni_request_derive/src/parse/message/parse.rs b/bomboni_request_derive/src/parse/message/parse.rs index cfcdc95..871942e 100644 --- a/bomboni_request_derive/src/parse/message/parse.rs +++ b/bomboni_request_derive/src/parse/message/parse.rs @@ -464,12 +464,6 @@ fn expand_parse_field(options: &ParseOptions, field: &ParseField) -> syn::Result } } - let default_expr = if let Some(default) = field.default.as_ref() { - quote! { #default } - } else { - quote! { Default::default() } - }; - // Source field for nested messages is always wrapped in `Option` let source_option = field.source_option || is_option @@ -537,23 +531,30 @@ fn expand_parse_field(options: &ParseOptions, field: &ParseField) -> syn::Result }); } } else { - if source_option { - if field.default.is_some() { - parse.extend(quote! { - let target = target.unwrap_or_else(|| #default_expr); - }); + parse.extend(if source_option { + if let Some(default) = field.default.as_ref() { + quote! { + let target = if let Some(target) = target { + #parse_source + target + } else { + #default + }; + } } else { - parse.extend(quote! { + quote! { let target = target.ok_or_else(|| { RequestError::field( #field_name, CommonError::RequiredFieldMissing, ) })?; - }); + #parse_source + } } - } - parse.extend(parse_source); + } else { + parse_source + }); } if is_box { diff --git a/bomboni_request_derive/src/parse/message/write.rs b/bomboni_request_derive/src/parse/message/write.rs index 0d6b6c0..e2d95e6 100644 --- a/bomboni_request_derive/src/parse/message/write.rs +++ b/bomboni_request_derive/src/parse/message/write.rs @@ -175,12 +175,6 @@ fn expand_write_field(options: &ParseOptions, field: &ParseField) -> TokenStream let source = value.#target_ident; }; - let default_expr = if let Some(default) = field.default.as_ref() { - quote! { #default } - } else { - quote! { Default::default() } - }; - let source_option = field.source_option || is_option || (is_nested @@ -202,8 +196,12 @@ fn expand_write_field(options: &ParseOptions, field: &ParseField) -> TokenStream } } else { quote! { - let source = source.unwrap_or_else(|| #default_expr); - #write_target + let source = if let Some(source) = source { + #write_target + source + } else { + Default::default() + }; } }); } else { diff --git a/bomboni_request_derive/src/parse/oneof/parse.rs b/bomboni_request_derive/src/parse/oneof/parse.rs index 61fa6e4..5042fc7 100644 --- a/bomboni_request_derive/src/parse/oneof/parse.rs +++ b/bomboni_request_derive/src/parse/oneof/parse.rs @@ -321,12 +321,6 @@ fn expand_parse_variant( } } - let default_expr = if let Some(default) = variant.default.as_ref() { - quote! { #default } - } else { - quote! { Default::default() } - }; - let source_option = variant.source_option || is_option; if is_option { @@ -386,23 +380,30 @@ fn expand_parse_variant( }); } } else { - if source_option { - if variant.default.is_some() { - parse.extend(quote! { - let target = target.unwrap_or_else(|| #default_expr); - }); + parse.extend(if source_option { + if let Some(default) = variant.default.as_ref() { + quote! { + let target = if let Some(target) = target { + #parse_source + target + } else { + #default + }; + } } else { - parse.extend(quote! { + quote! { let target = target.ok_or_else(|| { RequestError::field( variant_name, CommonError::RequiredFieldMissing, ) })?; - }); + #parse_source + } } - } - parse.extend(parse_source); + } else { + parse_source + }); } if is_box { diff --git a/bomboni_request_derive/src/parse/oneof/write.rs b/bomboni_request_derive/src/parse/oneof/write.rs index b63d0b8..4916913 100644 --- a/bomboni_request_derive/src/parse/oneof/write.rs +++ b/bomboni_request_derive/src/parse/oneof/write.rs @@ -223,12 +223,6 @@ fn expand_write_variant(options: &ParseOptions, variant: &ParseVariant) -> Token let source = value; }; - let default_expr = if let Some(default) = variant.default.as_ref() { - quote! { #default } - } else { - quote! { Default::default() } - }; - let source_option = variant.source_option || is_option; if is_option { @@ -243,8 +237,12 @@ fn expand_write_variant(options: &ParseOptions, variant: &ParseVariant) -> Token } } else { quote! { - let source = source.unwrap_or_else(|| #default_expr); - #write_target + let source = if let Some(source) = source { + #write_target + source + } else { + Default::default() + }; } }); } else { diff --git a/bomboni_template/Cargo.toml b/bomboni_template/Cargo.toml index 1ffcf38..41cecd7 100644 --- a/bomboni_template/Cargo.toml +++ b/bomboni_template/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bomboni_template" -version = "0.1.47" +version = "0.1.48" authors = ["Tin Rabzelj "] description = "Utilities for working Handlebars templates. Part of Bomboni library." repository = "https://github.com/tinrab/bomboni" @@ -17,8 +17,8 @@ path = "src/lib.rs" testing = [] [dependencies] -bomboni_common = { path = "../bomboni_common", version = "0.1.47" } -bomboni_proto = { version = "0.1.47", path = "../bomboni_proto", features = [ +bomboni_common = { path = "../bomboni_common", version = "0.1.48" } +bomboni_proto = { version = "0.1.48", path = "../bomboni_proto", features = [ "json", ] } thiserror = "1.0.51"