Skip to content

0.5.0

Compare
Choose a tag to compare
@matsadler matsadler released this 11 Feb 16:41
· 329 commits to main since this release

Magnus 0.5.0 adds many features, a handful of fixes, and some API changes.

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.

Fixes

RStruct was missing an implementation of the ReprValue trait that would allow it to be passed to functions that require a value that is already a Ruby object. This trait implementation has now been added.

When converting Ruby values to RArray (or Vec<T>, [T; 1], or (T,)), an error will now be returned if given a non-Array (or non to_ary-able) value, rather than wrapping it in an array (see RArray::to_ary for the old behaviour).

Changes

There have been some internal changes to start making Magnus safe to use with multithreaded code. Many functions are now documented as panicking when called from a non-Ruby thread. This check is currently only performed in debug builds, as there is no api to avoid the performance hit of this check (calling these functions from a non-Ruby thread in a release build is undefined behaviour).

The IntoValue trait is now used instead of Into<Value> for converting to Ruby types. The Into<Value> implementations will be removed in the next release.

use magnus::prelude::* will now import traits anonymously.

New features

The bytes-crate feature can be enabled to allow automatic conversions between bytes::Bytes and Ruby strings.

typed_data::Obj<T>, is a Ruby object wrapping a Rust type known to be T. Previously you could declare a function accepting &T to receive a reference to the Rust data wrapped in a Ruby object, but you wouldn't have access to the wrapping object. Or if you declared the argument as Value you could get the wrapping object, but it was awkward to get the inner Rust data. typed_data::Obj<T> gets you the best of both worlds. See the typed_data_obj.rs test for an example.

TypedData::class_for can be implemented to customise the class on a case by case basis when wrapping Rust data in a Ruby object. See the docs for details. A simple interface to this is enabled with the #[wrap] macro now allowing #[magnus(class = "...")] attributes on enum variants.

The typed_data::Hash and typed_data::IsEql traits are automatically implemented for compatible types, providing Ruby compatible #hash and #eql? methods ready to be bound to your object.

error::Result<T> as a shorthand for std::result::Result<T, Error>.

The following Ruby API functions are now implemented in Magnus:

See the changelog for more details.

Thanks

  • @ianks for continued improvements to the foundational rb-sys crate, the idea for the typed_data::Obj<T> feature, some CI improvements for Magnus, and the auto wb_protected flag feature.
  • @gjtorikian for reporting the surprising Array conversion behaviour.
  • @georgeclaghorn for adding funcall_public and error::Result<T>.
  • @Maaarcocr for reporting an issue where Vec<Value> could be passed as an argument to Ruby (Value should never be stored in a heap allocated struct like Vec) that inspired the design of the IntoValue trait.
  • @ankane for the idea behind TypedData::class_for and #[magnus(class = "...")] on enum variants.
  • @elct9620 for reporting an issue with embed::init and the ruby-static feature that resulted in a change that gives better error messages from embed::init.
  • @cramt for the bytes-crate feature.