-
Notifications
You must be signed in to change notification settings - Fork 290
Class macro #1117
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
base: main
Are you sure you want to change the base?
Class macro #1117
Conversation
- Class trait - #[neon::class] macro - Instance extractor - supports ability to construct instances both from JS and Rust - a couple of unit tests remaining to do: - how much subclassing can we support? - #[neon::export(class)] shorthand - cleanup
- allow #[neon(name = "foobar")] explicit renames in method attributes
- implementation of async and task methods
- doesn't yet work in conjunction with async fn
- takes &self - doesn't implicitly clone - added a couple of tests
- channel not yet working
- bugfix: async fn with json attribute now works - add missing files that I meant to add in earlier commits!
- clarifications in export macro rustdocs - suppress lint warnings for auto-generated hidden exports
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1117 +/- ##
==========================================
+ Coverage 82.85% 83.24% +0.38%
==========================================
Files 74 81 +7
Lines 4701 5610 +909
Branches 4701 5610 +909
==========================================
+ Hits 3895 4670 +775
- Misses 713 830 +117
- Partials 93 110 +17 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- automatically wrap RefCell<T> instead of T - no longer require Clone unless class includes async or task methods
| value: String, | ||
| } | ||
|
|
||
| #[neon::export(class, name = "RenamedClass")] |
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.
name is a bit ambiguous here. Are we renaming the class or are we renaming the export? Should we have two different name fields?
// #[neon::export(class, name = "RenamedClass")]
// impl CustomNamedClass {}
// equivalent to...
export const RenamedClass = class CustomNamedClass {}
// #[neon::export(class(name = "RenamedClass"))]
// impl CustomNamedClass {}
// equivalent to...
export const CustomNamedClass = class RenamedClass {}
// #[neon::export(class(name = "RenamedClass"), name = "RenamedClass")]
// impl CustomNamedClass {}
// equivalent to...
export class RenamedClass {}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.
Possibly to avoid duplication in the common case of renaming both:
// #[neon::export(class, name = "RenamedClass")]
// impl CustomNamedClass {}
// equivalent to...
export const RenamedClass = class CustomNamedClass {}
// #[neon::export(class(name = "RenamedClass"))]
// impl CustomNamedClass {}
// equivalent to...
export class RenamedClass {}
// #[neon::export(class(name = "RenamedClass"), name = "CustomNamedClass")]
// impl CustomNamedClass {}
// equivalent to...
export const CustomNamedClass = class RenamedClass {}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.
After discussing, we came to this conclusion:
// CASE 1: renames both to RenamedClass, but we won't document this
#[neon::export(class, name = "RenamedClass")]
impl CustomNamedClass {}
// CASE 2: renames both to RenamedClass, we will document this
#[neon::export(class(name = "RenamedClass"))]
impl CustomNamedClass {}
// CASE 3: renames class to RenamedClass and export to ExportedRenamedClass, we will document this
#[neon::export(class(name = "RenamedClass"), name = "ExportedRenamedClass"]
impl CustomNamedClass {}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.
Rationale:
- Case 1 mirrors JS syntax and avoids accidentally leaking the internal Rust implementation details
- Case 2 is nicely compositional
- Case 3 is probably rare but again it's compositional
- Instance has been deleted - updated docs
|
Plan:
|
- macro generates a `where Self: Clone` clause to conditionally require Clone only if a function takes the class type as a parameter - use a compiler workaround hack to enable this functionality -- see rust-lang/rust#48214 (comment)
…ing them with ObjectExpected errors
- added better error messages for type errors in method arguments
Example:
Tasks:
#[neon::export(class)]shortcut