Releases: matsadler/magnus
0.7.1
0.7.0
Magnus 0.7.0 adds many features, but should be largely compatible with 0.6.
Magnus is a Rust library providing a high-level easy-to-use interface to the C API of the Ruby programming language. Magnus lets you write Ruby extension libraries (or 'gems') in Rust, or embed Ruby in your Rust program.
API changes
Magnus 0.5 and earlier would allow you to create Ruby objects with associated functions, like RArray::new
. In Magnus 0.6 a new set of APIs for creating Ruby objects was added, as methods on a Ruby
handle that can only be obtained on a Ruby thread. 0.7 begins the deprecation of the associated functions with the old-api
feature. This feature is enabled by default, but if disabled the old-api
functions will issue deprecation warnings. Disable this feature to get an early start on migrating these functions to the new API.
As part of the same effort, closures and functions used as Ruby blocks or procs now take an additional first argument of &Ruby
.
The ruby-static
feature has been removed. Instead enable the feature for rb-sys
in your Cargo.toml like so:
rb-sys = { version = "*", features = ["ruby-static"] }
New Features
- Support for Ruby's
Thread
api via methods to create threads on theRuby
type and theThread
type. - Support for Ruby's
Mutex
api via methods to create a mutex on theRuby
type and theMutex
type. - Support for Ruby's
Fiber
api via methods to create fibers on theRuby
type and theFiber
type (on Ruby versions 3.1 and up). - A
Time
type representing instances of Ruby'sTime
class that will convert to/fromstd::time::SystemTime
. r_array::TypedArray
, a Ruby Array that may only contain elements of typeT
. On creation the Array is hidden from Ruby, and must be consumed to pass it to Ruby (where it reverts to a regular untyped Array). It is then inaccessible to Rust.magnus::Integer
now implementsPartialEq
,PartialOrd
,Add
,Sub
,Mul
, andDiv
so it can be used with mathematical operators like+
and-
.Ruby::define_data
for working with Ruby'sData
class (Ruby 3.3 and up only).RArray
implementsIntoIterator
.IntoError
is a new trait for converting types tomagnus::Error
. Functions returning to Ruby can now returnResult
where the error type is any type that implementsIntoError
.
Upgrading
Upgrading from Magnus 0.6 should be straightforward. If upgrading from 0.5 or earlier, it's recommended to upgrade to 0.6 first.
See the changelog for all the changes.
Thanks
@Maaarcocr for implementing the Add
et al traits for Integer
.
@adampetro for contributions to the implementation of IntoIterator
for RArray
.
@macournoyer for fixes to Error
.
@y-yagi and @gjtorikian for fixing typos.
0.6.4
Magnus 0.6.4 is a patch release, with 1 fix.
Lazy
could deadlock when called for the first time from multiple threads simultaneously.
The fix for results in a slight change in expected behaviour. If multiple threads attempt first access at the same time the func
given to Lazy::new
may be called more than once, but all threads will receive the same value.
Thanks to @choubacha for reporting this issue, along with an excellent repro.
0.6.3
0.6.2
0.6.1
0.5.5
Magnus 0.5.5 is a patch release, with 1 change.
This release adds support for rb-sys
' stable-api feature. This necessitates upping the minimum supported Rust version to 1.60.
Additionally, Ruby 2.6 support requires enabling rb-sys
' stable-api-compiled-fallback
feature in your Cargo.toml
like so:
rb-sys = { version = "*", default-features = false, features = ["stable-api-compiled-fallback"] }
0.6.0
Magnus 0.6.0 makes some breaking API changes to improve thread safety. A handful of fixes and new features are also included.
Magnus is a Rust library providing a high-level easy-to-use interface to the C API of the Ruby programming language. Magnus lets you write Ruby extension libraries (or 'gems') in Rust, or embed Ruby in your Rust program.
Thread Safety
Previous versions of Magnus have ignored thread safety in aid of getting something working, but support for threads and running Rust code outside of the Global VM Lock via rb_thread_call_without_gvl
have been common feature requests. This release prepares for the introduction of those features with some breaking API changes.
To this end all APIs that create Ruby objects have been moved to a new Ruby
handle which can only be obtained on a Ruby thread. For example RArray::new()
becomes Ruby::ary_new(&self)
(currently RArray::new()
still exists as a wrapper around Ruby::get().unwrap().ary_new()
). Default
implementations have been removed. Additionally Ruby types are no longer Send
& Sync
. An Opaque
wrapper type can be used to pass Ruby types between threads where they can only be unwrapped on a Ruby thread.
To make getting ahold of the Ruby
handle simple, functions bound as Ruby methods with method!()
and function!()
, along with the function marked with #[magnus::init]
optionally take &Ruby
as a first argument.
Other API Changes
The minimum supported Rust version is now 1.61.
The bytes-crate
and rb-sys-interop
features have been renamed to bytes
and rb-sys
respectively.
Previously all Ruby types, such as RString
, RArray
, etc Deref
'd to Value
, allowing Value
methods to be called on all Ruby types. This is no longer the case. All Value
methods have been moved to the ReprValue
trait, which is implemented by Value
and all other Ruby types.
This allows typed_data::Obj<T>
to Deref
to T
, turning typed_data::Obj
into a 'smart pointer' type that makes advanced use of wrapped data much more pleasant.
New Features
rb_assert!()
macrovalue::Lazy
lazily initialises a Ruby value so it can be assigned to astatic
- Support for subclassable wrapped Rust data via
Class::define_alloc_func
andRuby::obj_wrap_as
- The
kwargs!()
macro andKwArgs
type can be used to pass keyword arguments toReprValue::funcall
, et al. - Documentation examples for almost every function
Upgrading
If you encounter a lot of deprecation warnings when upgrading it may be easier to ignore warnings to concentrate on fixing errors, assuming your project is setup with a Rake and a 'compile' task this can be done with:
RUSTFLAGS=-Awarnings rake compile
It is also possible to ignore errors due to Value
no longer being Send + Sync
by activating the deprecated-send-sync-value
feature:
magnus = { version = "0.6", features = ["deprecated-send-sync-value"] }
This feature is intended purely as a convenience when upgrading and will be removed with the next release.
To make a Ruby type Send + Sync
wrap it with Opaque::from
. To get the Ruby type back use Ruby::get_inner()
.
Functions on Value
have moved to the ReprValue
trait, It is recommended to import this with use magnus::prelude::*
. Magnus' prelude
module only imports traits, and does so anonymously, so there is minimal chance of it causing problems.
There are no longer From<T>
/Into
implementations for Value
. In a lot of cases this can be replaced with .as_value()
. For 'wrapped' structs you will need to wrap them with Ruby::obj_wrap
first. Internally Magnus uses the IntoValue
trait, which is available publicly with use magnus::IntoValue
.
See the changelog for all the changes.
Thanks
@wfchandler for reporting issues with subclassing wrapped types.
@adampetro for implementing keyword support in funcall
, et al.
0.5.4
0.5.3
Magnus 0.5.3 is a patch release, with 1 addition.
Added Value::as_value
method that can be called on any Ruby type (as all Ruby types deref to Value
) as a forward-compatible way to convert a Ruby type to Value
.
This method should be prefered over dereferencing (e.g. *example
), and the From
/Into
traits (e.g. Value::from(example)
and let v: Value = example.into()
) as in future versions of Magnus Ruby types will not dereference to Value
(Value
's methods will move to a trait) and From
/Into
will not be implemented.