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

Provides two macros to make model creation more convenient #643

Merged
merged 8 commits into from
May 31, 2022

Conversation

gabsi26
Copy link
Contributor

@gabsi26 gabsi26 commented May 29, 2022

An initial PR to get this rolling.

This PR deals with #72. Where attributed_arguments is a crude implementation of an idea #72 (comment)

The attribute #[value()] is required for each parameter the user wants to pass to the model it accepts different forms

  • #[value(3)] sets default value to 3
  • #[value(default=3)] same as above
    min and max can additionally be supplied like this:
    #[value(min=1, max=2)]
    As long as either one of the three values is supplied a default will be set, min and max are currently only used if no default is provided to set it. Where min takes precedence over max.
    Later on a doc comment containing the provided min and max values should be introduced.

@gabsi26 gabsi26 requested a review from hannobraun as a code owner May 29, 2022 14:10
@gabsi26 gabsi26 changed the title Proc me up scotty rovides two proc macros to Provides two macros to make model creation more convenient May 29, 2022
@hannobraun
Copy link
Owner

Thank you for the pull request, @gabsi26! I'll take a look later, possibly tomorrow.

Copy link
Owner

@hannobraun hannobraun left a comment

Choose a reason for hiding this comment

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

Thank you again for the pull request, @gabsi26! This is an awesome improvement!

I left a bunch of comments with specific suggestions, as well as more general remarks on where I'd like to see things going. Feel free to address those in a follow-up PR, if you're up for it. I'll merge this one now, as it provides an excellent base for further iteration.

Comment on lines 12 to +14
"crates/fj-viewer",
"crates/fj-proc",

Copy link
Owner

Choose a reason for hiding this comment

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

The rest of that list is alphabetically sorted. Would be nice to keep that. Also, no need for an empty line.

Comment on lines +17 to +19
"crates/fj-proc",


Copy link
Owner

Choose a reason for hiding this comment

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

There's the same crate a second time. I'm surprised that doesn't result in some kind of error! 😄

Comment on lines +11 to +13

[dependencies.fj-proc]
path = "../../crates/fj-proc"
Copy link
Owner

Choose a reason for hiding this comment

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

I think it should be possible, to re-export fj-proc from fj (pub use fj_proc;). Then we wouldn't need the extra dependency, and would also have a simpler syntax in the models (fj::model instead of fj_proc::model).

bracketed, parenthesized, parse::Parse, parse_macro_input, parse_quote,
};

pub fn attributed_arguments(_: TokenStream, input: TokenStream) -> TokenStream {
Copy link
Owner

Choose a reason for hiding this comment

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

I think having two different attributes (and two different models for testing/demonstrating) them is overkill. I like the approach implemented in this one much better. It would be better, if this just replaced the other one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The first one was more or less just left in because it was the first one I came up with. So more for completeness than anything else. I'll get rid of it :)

_ => {}
}
} else {
default = Some(value.val.clone());
Copy link
Owner

Choose a reason for hiding this comment

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

Maybe it would be better not to have this fallback, and always require an explicit default = to specify default values. Would be more verbose in the simple case, but also easier to read and understand.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I'll simplify the macro to not allow for this implicit fallback

default = Some(value.val.clone());
}
}
let [default, min, max] = determine_default(default, min, max);
Copy link
Owner

Choose a reason for hiding this comment

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

I think the behavior of this function, using min or max as the default, if no default is provided, is unexpected and potentially confusing for users. It would probably be clearer to just have no default, if none is provided, and fail with an error message, if the user doesn't provide a value for a default-less parameter.

Comment on lines +55 to +59
/// Represents one parameter given to the `model`
/// `#[value(default=3, min=4)] num_points: u64`
/// `^^^^^^^^^^^^^^^^^^^^^^^^^^ ~~~~~~~~~~ ^^^-- ty`
/// ` | |`
/// ` attr ident`
Copy link
Owner

Choose a reason for hiding this comment

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

Nice style of documentation 👍

gabsi26 added 8 commits May 31, 2022 13:49
With this change the `model` function is a lot nicer to write
default values are provided as macro arguments
currently all arguments **must** have a default value defined this way
there are also no checks in place to ensure the default is valid
 for the type of the argument

Signed-off-by: gabsi26 <[email protected]>
This is a first iteration on a asuggested way to implement modelling
 convenience

Signed-off-by: gabsi26 <[email protected]>
The struct `AttributeParameter`was only used for its `new` method,
thus it was replaced by `determine_default()`

Some comments were added to make the purpose of structs a bit clearer

Signed-off-by: gabsi26 <[email protected]>
@hannobraun hannobraun force-pushed the proc_me_up_scotty branch from 20a4dd9 to 78b4756 Compare May 31, 2022 11:49
@hannobraun hannobraun enabled auto-merge May 31, 2022 11:49
@hannobraun hannobraun merged commit 3daab76 into hannobraun:main May 31, 2022
@hannobraun
Copy link
Owner

One additional note: I just discovered, that Cargo.lock wasn't up-to-date, meaning Cargo will immediately update it on any cargo build, cargo test, or similar. Then there will be a local change, which can confuse contributors and could interfere with work in the Git history (like somebody running a git bisect).

No big deal, I'll fix it (I'm about to do my weekly cargo update anyway). But in general, it would be nicer if changes to Cargo.lock were committed in the same commit that triggered them (like in this case, the commit that adds the new crate).

@gabsi26 gabsi26 deleted the proc_me_up_scotty branch May 31, 2022 12:06
@gabsi26 gabsi26 mentioned this pull request May 31, 2022
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