Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces field type transformations to the substruct macro, allowing substruct fields to have different types than their parent fields through fallible conversions. The main feature enables transforming Option<T> to T via unwrap or converting between types using TryInto.
Key changes:
- Added
unwraptransform to convertOption<T>fields toTin substructs - Added
try_intotransform to convert field types usingTryInto<U> - Generated
TryFromimplementations instead ofFromwhen transforms are used - Created conversion error types for handling transformation failures
Reviewed Changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/expr.rs | Extended expression parser to handle transform syntax like Name(unwrap) and Name(try_into = Type) |
| src/substruct.rs | Added transform logic, field configuration tracking, and TryFrom implementation generation |
| src/lib.rs | Updated documentation with transformation examples and usage patterns |
| tests/it.rs | Added comprehensive tests for unwrap, try_into, and mixed transformation scenarios |
| tests/ui/pass/*.rs | Added UI test cases covering various transformation combinations and edge cases |
| tests/ui/fail/*.rs | Added error test cases for invalid transform syntax |
| README.md | Enhanced documentation with transformation examples and usage guide |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| let a = b.into_a(5); | ||
|
|
||
| assert!(matches!(a, A(5, 32))) | ||
| assert!(matches!(a, A(5, 32))); |
There was a problem hiding this comment.
Missing semicolon in assert! macro call. This was fixed from the previous version.
| if !attr.path().is_ident("doc") { | ||
| return Err(syn::Error::new_spanned( | ||
| &attr, | ||
| attr, |
There was a problem hiding this comment.
Removed unnecessary reference operator (&) when the argument is already a reference. This improves code clarity.
|
|
||
| for error in self.errors.drain(..) { | ||
| self.tokens.extend(error.into_compile_error()) | ||
| self.tokens.extend(error.into_compile_error()); |
There was a problem hiding this comment.
Missing semicolon added to complete the statement properly.
| }, | ||
| syn::Data::Union(data) => self.filter_fields_named(&mut data.fields, name), | ||
| }; | ||
| } |
There was a problem hiding this comment.
Replaced semicolon with closing brace to properly close the match expression.
| .keys() | ||
| .cloned() | ||
| .map(|key| key.into_ident()) | ||
| .map(IdentOrIndex::into_ident) |
There was a problem hiding this comment.
Simplified closure to method reference for better readability and performance.
|
|
||
| if args.len() > 5 { | ||
| attrs.push(syn::parse_quote!(#[allow(clippy::too_many_arguments)])) | ||
| attrs.push(syn::parse_quote!(#[allow(clippy::too_many_arguments)])); |
There was a problem hiding this comment.
Missing semicolon added to complete the statement.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Hi there, first of all thanks for the crate.
Sometimes it's useful to have a substruct have a different field than (but fallibly convertible to) the parent one, such as
Option<T>->T, orT: TryInto<U>->U.This PR enables that by introducing transforms:
unwrapandtry_into. When present, the crate generates aTryFromimplementation instead ofFromand an associated error type.