Unlike the FFI and JNI bridges (#383 and #384), the argument handling for wrapped Rust values in Node can't be handled with a simple blanket trait impl. Add a set of new traits and helpers to capture most of the complexity so that the macro doesn't have anything too complicated in it:
BridgeHandle - mostly a marker trait, like ffi::BridgeHandle and jni::BridgeHandle, but has a Strategy associated type to choose between Immutable-style boxing and Mutable-style boxing.
BridgeHandleStrategy - chooses between Immutable-style boxing (no extra wrapper) and Mutable-style boxing (wrap in a RefCell for safety). Can also be used to guard a particular function to only work with immutable or mutable bridge handles
BoxContentsFor<T> - shorthand for T::Strategy::JsBoxContents, which Rust can't always resolve without fully spelling out the traits involved. In practice, this will either be T or RefCell<T>.
BoxedBorrow - a struct that represents a synchronous borrow of a wrapped value. By making the borrow type a generic parameter, we can have BoxedBorrow<&T> (immutable borrow of an immutable value), BoxedBorrow<Ref<T>> (immutable borrow of a mutable value), and BoxedBorrow<RefMut<T>> (mutable borrow of a mutable value).
PersistentBoxedValue - a struct for asynchronously borrowing a wrapped value (by keeping around its JavaScript wrapper as a GC root). This type already existed, but it's been tweaked so that it's more similar to BoxedBorrow and PersistentArrayOfBoxedValues.
PersistentArrayOfBoxedValues - a struct for borrowing a whole array of boxed values and, uh, hoping JavaScript won't change the array out from under us. This also already existed, but the safety is more clearly documented now.
clone_from_wrapper and clone_from_array_of_wrappers - functions to clone a bunch of boxed mutable values, so that they won't change during asynchronous use. Not the most efficient thing, but pretty straightforward, at least.
All of the convert.rs files also need some reorganizing and the contents of this commit message should probably turn into a module-level doc comment once it settles.
Updated with most of these suggestions, except changing the field names of BorrowedJsBoxedBridgeHandle. I'm still open to changing those as well but I don't think the suggested names are accurate.
Unlike the FFI and JNI bridges (#383 and #384), the argument handling for wrapped Rust values in Node can't be handled with a simple blanket trait impl. Add a set of new traits and helpers to capture most of the complexity so that the macro doesn't have anything too complicated in it:
BridgeHandle - mostly a marker trait, like
ffi::BridgeHandle
andjni::BridgeHandle
, but has a Strategy associated type to choose between Immutable-style boxing and Mutable-style boxing.BridgeHandleStrategy - chooses between Immutable-style boxing (no extra wrapper) and Mutable-style boxing (wrap in a RefCell for safety). Can also be used to guard a particular function to only work with immutable or mutable bridge handles
BoxContentsFor<T>
- shorthand forT::Strategy::JsBoxContents
, which Rust can't always resolve without fully spelling out the traits involved. In practice, this will either beT
orRefCell<T>
.BoxedBorrow - a struct that represents a synchronous borrow of a wrapped value. By making the borrow type a generic parameter, we can have
BoxedBorrow<&T>
(immutable borrow of an immutable value),BoxedBorrow<Ref<T>>
(immutable borrow of a mutable value), andBoxedBorrow<RefMut<T>>
(mutable borrow of a mutable value).PersistentBoxedValue - a struct for asynchronously borrowing a wrapped value (by keeping around its JavaScript wrapper as a GC root). This type already existed, but it's been tweaked so that it's more similar to BoxedBorrow and PersistentArrayOfBoxedValues.
PersistentArrayOfBoxedValues - a struct for borrowing a whole array of boxed values and, uh, hoping JavaScript won't change the array out from under us. This also already existed, but the safety is more clearly documented now.
clone_from_wrapper
andclone_from_array_of_wrappers
- functions to clone a bunch of boxed mutable values, so that they won't change during asynchronous use. Not the most efficient thing, but pretty straightforward, at least.All of the convert.rs files also need some reorganizing and the contents of this commit message should probably turn into a module-level doc comment once it settles.