-
Notifications
You must be signed in to change notification settings - Fork 114
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: increase hygiene #628
Conversation
Please rebase on top of latest |
1b49fed
to
394e91b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the amount of changes that need to be done here can be reduced. Instead of fully qualifying everything, which is tedious, you could import some items with the use
directive. As long as you are importing in a scope created by the macro which does not pollute the global namespace, it should be fine. For example, importing inside a method body created by the derive macro is OK, but importing items just before the impl
block is not.
It would also be nice to have a test that verifies that the macros are indeed hygienic. It shouldn't be hard to add, just create an integration test (in scylla-cql or scylla crate) that uses #[no_implicit_prelude]
and use the derive macros there. The scylla
crate would be an exception, you will have to import it. Ref: https://gist.github.com/Kestrer/8c05ebd4e0e9347eb05f265dfb7252e1#test-your-macro-with-no_implicit_prelude
To make the macros more hygienic, add full paths to types in the generated code, so that the macros will still work even if the user uses the same names with different meanings in their code.
394e91b
to
28f6a20
Compare
In the last rebase, I replaced the full paths with |
scylla-macros/src/parser.rs
Outdated
if !other.path().is_ident("scylla_crate") { | ||
continue; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this check could be extracted to the beginning of the for loop and the one done in Meta::NameValue
branch removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
scylla-macros/src/from_row.rs
Outdated
-> ::std::result::Result<Self, scylla::cql_to_rust::FromRowError> { | ||
use scylla::frame::response::result::CqlValue; | ||
use scylla::cql_to_rust::{FromCqlVal, FromRow, FromRowError}; | ||
impl #impl_generics #path::_macro_internal::FromRow for #struct_name #ty_generics #where_clause { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having to mention _macro_internal
every time sounds redundant. Could the get_path
function return a path with _macro_internal
appended? It will save some typing and prevent mistakes if somebody forgets to append _macro_internal
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was expecting that maybe we will use also some paths not including _macro_internal
but we ended up not using any, so I added it in get_path
and removed elsewhere
scylla/tests/hygiene.rs
Outdated
@@ -0,0 +1,64 @@ | |||
#![no_implicit_prelude] | |||
|
|||
extern crate scylla as _scylla; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to have a similar test for scylla_cql, to make sure that the _macro_internal
module exports everything properly. Preferably, without code duplication - maybe via a declarative macro?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a test for the scylla_cql
crate, but I'm not completely sure it was what you expected, please take a look
scylla-macros/src/parser.rs
Outdated
match this_path { | ||
Some(path) => Ok(path), | ||
None => Ok(quote::quote!(scylla)), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this_path.unwrap_or_else(|| quote::quote!(scylla));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok(Ok)
scylla/tests/hygiene.rs
Outdated
|
||
let sv = test_struct.serialized().unwrap().into_owned(); | ||
let sv2 = tuple_with_same_layout.serialized().unwrap().into_owned(); | ||
assert_eq!(sv, sv2,); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: comma after sv2
is unnecessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
scylla/tests/hygiene.rs
Outdated
let test_struct = TestStruct { a: 16 }; | ||
fn get_row() -> Row { | ||
Row { | ||
columns: ::std::vec![Some(CqlValue::Int(16)),], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: comma before the ]
is unnecessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I wonder why cargo fmt
didn't catch that
Currently, the macros will only work, if the code using them has a dependency on the scylla driver, or on the scylla_cql if it's renamed to scylla. This is caused by the fact that the paths referring to the scylla code are hardcoded to use a `scylla` crate. As a result, if a someone uses the `scylla_cql` crate without renaming, or renames `scylla_cql` or `scylla` to a name differen name than `scylla`, the macros will not work. Similarily, when another crate re-exports the macros, or uses them in their own macros, it can only work if the crate is used under the name `scylla` and it additionally re-exports parts of the `scylla_cql` code that are used in the macro under the same paths. This patch adds a `scylla_crate` helper attribute that allows users to set the crate name that will export the code that is used in the macros. All the symbols that are used there are also additionally exported in a `_macro_internal` module to make re-exporting important code segments more convenient.
Add a test that confirms that the macros work even if the crate was renamed. The test checks both scylla and scylla_cql crates. The test found missing `use ::std::iter...` statements, so they're also added.
28f6a20
to
8bf5493
Compare
Thanks to scylladb#628, it is now possible to provide an explicit path to a crate which provides necessary items for the FromRow macro. It is now possible to use this macro from the `scylla` crate itself, as we just need to point it to the `scylla-cql` crate instead. The NodeInfoRow struct is introduced to represent rows fetched from system.local and system.peers. It looks nicer than using a 5-element tuple and will reduce some noise when performing refactors in the commits that follow.
Thanks to scylladb#628, it is now possible to provide an explicit path to a crate which provides necessary items for the FromRow macro. It is now possible to use this macro from the `scylla` crate itself, as we just need to point it to the `scylla-cql` crate instead. The NodeInfoRow struct is introduced to represent rows fetched from system.local and system.peers. It looks nicer than using a 5-element tuple and will reduce some noise when performing refactors in the commits that follow.
Thanks to scylladb#628, it is now possible to provide an explicit path to a crate which provides necessary items for the FromRow macro. It is now possible to use this macro from the `scylla` crate itself, as we just need to point it to the `scylla-cql` crate instead. The NodeInfoRow struct is introduced to represent rows fetched from system.local and system.peers. It looks nicer than using a 5-element tuple and will reduce some noise when performing refactors in the commits that follow.
Thanks to scylladb#628, it is now possible to provide an explicit path to a crate which provides necessary items for the FromRow macro. It is now possible to use this macro from the `scylla` crate itself, as we just need to point it to the `scylla-cql` crate instead. The NodeInfoRow struct is introduced to represent rows fetched from system.local and system.peers. It looks nicer than using a 5-element tuple and will reduce some noise when performing refactors in the commits that follow.
Thanks to scylladb#628, it is now possible to provide an explicit path to a crate which provides necessary items for the FromRow macro. It is now possible to use this macro from the `scylla` crate itself, as we just need to point it to the `scylla-cql` crate instead. The NodeInfoRow struct is introduced to represent rows fetched from system.local and system.peers. It looks nicer than using a 5-element tuple and will reduce some noise when performing refactors in the commits that follow.
Thanks to scylladb#628, it is now possible to provide an explicit path to a crate which provides necessary items for the FromRow macro. It is now possible to use this macro from the `scylla` crate itself, as we just need to point it to the `scylla-cql` crate instead. The NodeInfoRow struct is introduced to represent rows fetched from system.local and system.peers. It looks nicer than using a 5-element tuple and will reduce some noise when performing refactors in the commits that follow.
While trying to make my macros at https://github.com/wmitros/scylla-rust-udf/pull/1 more hygienic, I noticed that I also need the macros here to be more hygienic.
I'm posting this mostly to find out if I'm heading in the right direction with the changes, although this patch does pass tests if it turns out being close to a state ready for merging
- [ ] I added appropriateFixes:
annotations to PR description.