Skip to content

Conversation

@rliang
Copy link

@rliang rliang commented Sep 20, 2025

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, or T: TryInto<U> -> U.

This PR enables that by introducing transforms: unwrap and try_into. When present, the crate generates a TryFrom implementation instead of From and an associated error type.

Copilot AI review requested due to automatic review settings September 20, 2025 23:41
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 unwrap transform to convert Option<T> fields to T in substructs
  • Added try_into transform to convert field types using TryInto<U>
  • Generated TryFrom implementations instead of From when 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)));
Copy link

Copilot AI Sep 20, 2025

Choose a reason for hiding this comment

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

Missing semicolon in assert! macro call. This was fixed from the previous version.

Copilot uses AI. Check for mistakes.
if !attr.path().is_ident("doc") {
return Err(syn::Error::new_spanned(
&attr,
attr,
Copy link

Copilot AI Sep 20, 2025

Choose a reason for hiding this comment

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

Removed unnecessary reference operator (&) when the argument is already a reference. This improves code clarity.

Copilot uses AI. Check for mistakes.

for error in self.errors.drain(..) {
self.tokens.extend(error.into_compile_error())
self.tokens.extend(error.into_compile_error());
Copy link

Copilot AI Sep 20, 2025

Choose a reason for hiding this comment

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

Missing semicolon added to complete the statement properly.

Copilot uses AI. Check for mistakes.
},
syn::Data::Union(data) => self.filter_fields_named(&mut data.fields, name),
};
}
Copy link

Copilot AI Sep 20, 2025

Choose a reason for hiding this comment

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

Replaced semicolon with closing brace to properly close the match expression.

Copilot uses AI. Check for mistakes.
.keys()
.cloned()
.map(|key| key.into_ident())
.map(IdentOrIndex::into_ident)
Copy link

Copilot AI Sep 20, 2025

Choose a reason for hiding this comment

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

Simplified closure to method reference for better readability and performance.

Copilot uses AI. Check for mistakes.

if args.len() > 5 {
attrs.push(syn::parse_quote!(#[allow(clippy::too_many_arguments)]))
attrs.push(syn::parse_quote!(#[allow(clippy::too_many_arguments)]));
Copy link

Copilot AI Sep 20, 2025

Choose a reason for hiding this comment

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

Missing semicolon added to complete the statement.

Copilot uses AI. Check for mistakes.
rliang and others added 3 commits September 20, 2025 20:45
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant