This PR aims to rework the class and callback system as well as their associated macros.
Specifically the Class and Function objects, ClassDef and AsFunction traits and the bind macro.
Motivation
The current class and callback system was designed around a few functions which proved to be unsound (see #167 and #83).
To remedy this unsoundness these functions had to be removed.
This however lead to one no longer being able to access class data mutably or by reference the internal rust class for the duration of a Javascript object.
This in turn made these systems a lot harder to work with and caused a lot of boilerplate when implementing functions and classes in rust for Javascript.
This PR completely redesigns the class system, and aims to remove the restrictions put on by the removed functions as well as remove a bunch of restrictions which where in place even before the unsound functions where removed.
Changes
The following is a non-exhaustive overview of all the changes this PR makes.
Rust class data is now wrapped in a optional RefCell like object allowing users to once again access class data mutably and this time safely.
Rust class are not longer required to be static but can now life for 'js instead, making it easier to hold on to javascript objects in classes.
Removed the bind macro in favour of smaller macros methodsclass and function and Derive(Trace).
Simplified the JsFunction trait.
A rust function called from Javascript will by default ignore extra arguments just like Javascript functions do, a function can be to error instead by taking Exhaustive as an argument.
Introduced Borrow and BorrowMut for temporarily borrowing rust class data from a class object.
Introduced OwnedBorrow and OwnedBorrowMut which allow you to borrow rust class data for as long as the javascript object lives.
Renamed ClassDef to JsClass
Renamed JsFunction to IntoJsFunc.
Renamed HasRefs to Trace
Introduced class macro, any rust struct can be marked with #[rquickjs::class] and the macro will implement JsClass for the struct.
Introduced methods macro, a impl block for a class which implements JsClass can be marked with#[rquickjs::methods] and the macro will use the functions and constants defined in the block to implement class prototype and constructor object.
Introduced function macro, any function can be marked with #[rquickjs::function] and the macro will implement the IntoJsFunc trait for a type with a similar name, allowing a greater range of functions to be passed to javascript.
Removed SelfMethod, it is no longer possible to get references to borrows in closures passed to javascript, use OwnedBorrow or take a Class object and then call borrow on that object instead.
Introduced Constructor which is a sub type of Function and can only be created from functions which are constructors.
Made Array and Function sub types of object via Deref.
Reworked Outlives to be more general, allowing possible implementation for types which contain Javascript objects.
A type which implements JsClass now needs to implement Trace, this can be easily done with the Derive(Trace) macro.
Had to make Ctx no longer copy, holding onto Ctx now keeps the associated context alive.
This PR aims to rework the class and callback system as well as their associated macros. Specifically the
Class
andFunction
objects,ClassDef
andAsFunction
traits and thebind
macro.Motivation
The current class and callback system was designed around a few functions which proved to be unsound (see #167 and #83). To remedy this unsoundness these functions had to be removed. This however lead to one no longer being able to access class data mutably or by reference the internal rust class for the duration of a Javascript object. This in turn made these systems a lot harder to work with and caused a lot of boilerplate when implementing functions and classes in rust for Javascript.
This PR completely redesigns the class system, and aims to remove the restrictions put on by the removed functions as well as remove a bunch of restrictions which where in place even before the unsound functions where removed.
Changes
The following is a non-exhaustive overview of all the changes this PR makes.
RefCell
like object allowing users to once again access class data mutably and this time safely.'js
instead, making it easier to hold on to javascript objects in classes.bind
macro in favour of smaller macrosmethods
class
andfunction
andDerive(Trace)
.JsFunction
trait.Exhaustive
as an argument.Borrow
andBorrowMut
for temporarily borrowing rust class data from a class object.OwnedBorrow
andOwnedBorrowMut
which allow you to borrow rust class data for as long as the javascript object lives.ClassDef
toJsClass
JsFunction
toIntoJsFunc
.HasRefs
toTrace
class
macro, any rust struct can be marked with#[rquickjs::class]
and the macro will implementJsClass
for the struct.methods
macro, aimpl
block for a class which implementsJsClass
can be marked with#[rquickjs::methods]
and the macro will use the functions and constants defined in the block to implement class prototype and constructor object.function
macro, any function can be marked with#[rquickjs::function]
and the macro will implement theIntoJsFunc
trait for a type with a similar name, allowing a greater range of functions to be passed to javascript.SelfMethod
, it is no longer possible to get references to borrows in closures passed to javascript, useOwnedBorrow
or take aClass
object and then call borrow on that object instead.Constructor
which is a sub type ofFunction
and can only be created from functions which are constructors.Array
andFunction
sub types of object viaDeref
.Outlives
to be more general, allowing possible implementation for types which contain Javascript objects.JsClass
now needs to implementTrace
, this can be easily done with theDerive(Trace)
macro.Ctx
no longer copy, holding ontoCtx
now keeps the associated context alive.