Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scylla-macros: attributes for better control over name checks #882

Merged
merged 5 commits into from
Dec 15, 2023

Conversation

piodul
Copy link
Collaborator

@piodul piodul commented Dec 15, 2023

The PR introduces two attributes related to matching Rust struct fields by name in the new SerializeRow/SerializeCql macros:

  • #[scylla(rename = "xyz")] - instead of using the name of the field verbatim, the name provided in the attribute is used when matching to a column/bind marker/UDT field. This can be useful e.g. if the user has different naming convention in Rust code and in the schema definitions.
  • #[scylla(skip_name_checks)] - in enforce_order flavor, skips checking the names of the fields as they are being serialized. With this attribute, the names of the corresponding fields in Rust struct and UDT/columns/bind markers don't have to match at all, but their types still need to. This attribute is supposed to help migrate from the old IntoUserType/ValueList macros.

Refs: #802

Pre-review checklist

  • I have split my patch into logically separate commits.
  • All commit messages clearly explain what they change and why.
  • I added relevant tests for new features and bug fixes.
  • All commits compile, pass static checks and pass test.
  • PR description sums up the changes and reasons why they should be introduced.
  • I have provided docstrings for the public items that I want to introduce.
  • I have adjusted the documentation in ./docs/source/.
  • I added appropriate Fixes: annotations to PR description.

In some cases, it might be desirable to name the Rust struct fields
differently than the UDT fields (e.g. due to a different naming
convention). Add an attribute to the `SerializeCql` macro, inspired by
serde's `rename` attribute, which causes the fields to be matched on a
specified name instead of the Rust name.
Like we just did for `SerializeCql`, introduce a `rename` annotation to
`SerializeRow` which allows associating given Rust field to a column /
bind marker with given name, instead of matching on the Rust field name.
The motivation is similar as in the case of `SerializeCql`: sometimes,
users might want to use a different naming scheme in Rust and for the
column names.
Implement `Default` for `Flavor`, which allows to get rid of the
`Option` wrapper in the macro attributes struct and simplify some of the
code as a result.
Introduce an attribute to the `SerializeCql` macro which causes the
generated code to skip checking names of the serialized Rust fields
against the UDT field names. The motivation behind the attribute is to
ease transition off the old `IntoUserType` macro which blindly
serialized the fields of the struct as they are defined in the Rust
code. While it disables the name checks, type checking is still done, so
there is protection against type confusion, at least.
Introduces an attribute to `SerializeRow` macro which causes name checks
to be skipped when serializing in `enforce_order` flavor. The motivation
is the same as in the case of `SerializeCql` - the old `ValueList` macro
didn't have access to the bind marker names and types, and disabling the
name check might make it easier for some to transition off the old
macro.
@piodul piodul requested a review from Lorak-mmk December 15, 2023 10:58
@piodul piodul marked this pull request as ready for review December 15, 2023 11:20
Comment on lines +90 to +98
/// `#[scylla(skip_name_checks)]
///
/// _Specific only to the `enforce_order` flavor._
///
/// Skips checking Rust field names against names of the UDT fields. With this
/// annotation, the generated implementation will allow mismatch between Rust
/// struct field names and UDT field names, i.e. it's OK if i-th field has a
/// different name in Rust and in the UDT. Fields are still being type-checked.
///
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm wondering if it wouldn't be better to make this a new flavor instead of an attribute - one less place to make a mistake for a user. But seeing that it's a compile time error, maybe it doesn't matter?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not entirely sure either; implementation-wise it was more natural to add an attribute as it introduces very slight changes to how the enforce_order flavor generates code.

One argument that I see for leaving it as a separate attribute is that it disables some safety checks, while both current flavors don't compromise on safety. It's good to make the less safe option more verbose IMO.

In the future we should consider adding support for tuple structs which very natually fit into the enforce_order + skip_name_checks pattern, we could probably remove the current skip_name_checks attribute when doing that.

@Lorak-mmk Lorak-mmk merged commit 8f360c5 into scylladb:main Dec 15, 2023
8 checks passed
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.

2 participants