magnus 0.6.4

High level Ruby bindings. Write Ruby extension gems in Rust, or call Ruby code from a Rust binary.
Documentation
# Changelog

## [Unreleased]
### Added

### Changed

### Deprecated

### Removed

### Fixed

### Security

## [0.6.4] - 2024-05-08
### Fixed
- Potential deadlock in `Lazy` when accessed for the first time from
  multiple threads simultaneously.

## [0.6.3] - 2024-03-31
### Fixed
- Missing ` IntoValueFromNative` implementation for `Vec` and `HashMap`.

## [0.6.2] - 2023-09-18
### Fixed
- Compliation error in `bytes` feature.

## [0.6.1] - 2023-08-20
### Changed
- Support `rb-sys`' `stable-api` feature.

## [0.6.0] - 2023-07-28
### Added
- `value::Opaque` can be used to wrap a Ruby type to make it `Send` + `Sync`.
- `value::Lazy` lazily initialises a Ruby value so it can be assigned to a
  `static`.
- `value::OpaqueId` is a `Send` + `Sync` version of `value::Id`.
- `value::LazyId` is an `Id` with a `const` constructor so can be assigned to a
  `static` and derefs to `OpaqueId`.
- `error::OpaqueError` is a `Send` + `Sync` version of `Error`.
- The `#[magnus(opaque_attr_reader)]` attribute can be set on `Opaque` wrapped
  fields of a struct when deriving `TypedData` to generate a method to return
  the inner value.
- `Ruby::init` function to initialise Ruby when embedding Ruby in Rust that
  runs a function with Ruby initialised, passing `&Ruby`.
- `rb_assert!()` macro to assert a Ruby expression evaluates to a truthy value.
- `Class::undef_default_alloc_func` to remove a class' allocator function only
  if it is Ruby's default allocator function.
- `Class::obj_alloc` and `Class::define_alloc_func` for allocating an object
  without calling `initialize`, and for defining an allocator function.
- `RTypedData::wrap_as` & `typed_data::Obj<T>::wrap_as` can be used to
  dynamically set the class when wrapping Rust data in a Ruby object. This can
  be used to allow wrapped data to be subclassed in Ruby.
- `Exception::exception_class` returns the class of an exception as an
  `ExceptionClass`.
- The `kwargs!()` macro and `KwArgs` type can be used to pass keyword arguments
  to `ReprValue::funcall`, et al.

### Changed
- Minimum supported Rust version is now 1.61.
- The `bytes-crate` feature has been renamed to `bytes`.
- The `rb-sys-interop` feature has been renamed to `rb-sys`.
- Ruby types are no longer `Send` or `Sync`. These types can be made `Send` &
  `Sync` with the `deprecated-send-sync-value` feature. This feature is meant
  to ease upgrading and will be removed with the next release.
- `Value`'s methods moved to the `ReprValue` trait.
- `typed_data::Obj<T>` derefs to `T` so now `T`'s methods can be called
  directly on `typed_data::Obj<T>`.
- `ReprValue` and `TryConvert` added to `magnus::prelude`.
- `typed_data::Cmp`, `typed_data::Dup` and `typed_data::Inspect` traits to help
  with implementing `#<=>`, `#dup` & `#clone`, and `#inspect` methods for
  wrapped structs.
- Wrapped data must be `Sync` to enable `frozen_shareable` flag.
- `TypedData::class` and `TypedData::class_for` now take a `&Ruby` argument.
- `DataTypeFunctions::mark` and `DataTypeFunctions::compact` now take
  `&gc::Marker` and `&gc::Compactor` arguments respectively.
- Init function marked with `#[magnus::init]` optionally takes a `&Ruby`
  argument.
- Functions bound as Ruby methods with `method!()` and `function!()` optionally
  take `&Ruby` as a first argument.
- The value returned from `embed::init` derefs to `Ruby`.
- `DataTypeBuilder::new`/`DataType::builder` now take their `name` argument
  as a `'static CStr` (see the `magnus::data_type_builder!` macro to construct
  a `DataTypeBuilder` with a `'static CStr` `name`).
- All methods on `DataTypeBuilder` are now `const`, so `DataType` can be
  constructed in a `const` context and be assigned to a `static`.
- The `#[wrap]` and `#[derive(TypedData)]` macros now support setting the
  `#[magnus(unsafe_generics)]` attribute to allow deriving `TypedData` for
  types with generics. The derived implementation is not guaranteed to be
  correct.

### Deprecated
- `typed_data::Obj::get` as it is made redundant by the `Deref` implementation
  for `typed_data::Obj`.
- The `QTRUE`, `QFALSE`, and `QNIL constants. Please use `value::qtrue()`,
  `value::qfalse()`, and `value::qnil()`.
- `Class::undef_alloc_func`. Please use `Class::undef_default_alloc_func`.
- `Value::try_convert`, prefer `TryConvert::try_convert` or `T::try_convert`.
- `Binding`. To call methods on Ruby's binding, use `ReprValue::funcall` on a
  `Value` know to be an instance of Ruby's Binding class.
- `gc::{mark, mark_slice, mark_movable, location}`, instead use
  `gc::Marker::{mark, mark_slice, mark_movable}` and `Compactor::location`.
- `RStruct::as_slice`.

### Removed
- Inherent methods on `RClass`, import `magnus::Class` trait or
  `magnus::prelude::*`.
- `Into<Value>`/`From<T> for Value` implementations, use `IntoValue`.
- `Default` implementations for `Value`, `RClass`, and `ExceptionClass`.
- `Error` can no longer be directly constructed, must use `Error::new` or
  `Error::from`/`Exception::into`.
- `RString::append` (use `RString::buf_append`).
- `Error::runtime_error` (use `Error::new(exception::runtime_error(), msg)`).

### Fixed
- `RFloat::from_value` now returns `None` when value is a `Flonum`.

## [0.5.3] - 2023-04-07
### 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`.

## [0.5.2] - 2023-03-19
### Fixed
- Fixed compilation issue in `RBignum` on 32 bit platforms.

## [0.5.1] - 2023-02-18
### Fixed
- Documentation fixes.

## [0.5.0] - 2023-02-11
### Added
- `typed_data::Obj<T>`, a Ruby object wrapping a Rust type known to be `T`.
- `RArray::to_ary`, `RArray::assoc`, `RArray::rassoc`, and `RArray::cmp`.
- `RHash::with_capacity` new for Ruby 3.2.
- `RHash::bulk_insert`.
- `Value::hash` to generate a hash key for a Ruby object.
- `typed_data::Hash` and `typed_data::IsEql` traits to help with implementing
  `#hash` and `#eql?` methods for wrapped structs.
- Lots of `RString` methods: `capacity`, `cmp`, `comparable`, `drop_bytes`,
  `dump`, `ellipsize`, `offset`, `plus`, `times`, `replace`, `scrub`,
  `shared_replace`, `split`, `update`.
- `RRegexp::new`/`new_str`, `RRegexp::reg_match`, and `RRegexp::options`.
- The `backref_get` function to get the `RMatch` for the last regexp match.
- `RMatch::nth_defined`, `RMatch::nth_match`, `RMatch::backref_number`,
  `RMatch::matched`, `RMatch::pre`, `RMatch::post`, and `RMatch::last`
- `RBignum::is_positive`/`is_negative`.
- `new`, `num`, and `den` for `RRational`, plus `rationalize` and
  `rationalize_with_prec` for `Float`.
- `RComplex::new`, `polar`, `real`, `imag`, `conjugate`, `abs` & `arg`.
- New `Numeric` trait implemented for `Integer`, `Float`, `RRational`,
  `RComplex`, etc. Exposes functions for applying operators to numeric types
  following Ruby's coercion protocol.
- `value::Id::new` added to replace `value::Id::from`.
- `TypedData::class_for` can be implemented to customise the class on a case by
  case basis when wrapping Rust data in a Ruby object.
- The `#[wrap]` and `#[derive(TypedData)]` macros now allow setting
  `#[magnus(class = "...")]` on enum variants to customise the class per
  variant when wrapping enums in a Ruby object.
- `Value::funcall_public` calls a public method, returning an error for a
  private or protected method.
- `error::Result<T>` is shorthand for `std::result::Result<T, Error>`.
- `embed::setup` to perform minimal initialisation of Ruby for environments
  where `embed::init` doesn't work.
- The `bytes-crate` feature can be enabled to allow automatic conversions
  between `bytes::Bytes` and Ruby strings.

### Changed
- When converting Ruby values to `RArray` (or `Vec<T>`, `[T; 1]`, or `(T,)`),
  an error will 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).
- `r_typed_data::{DataType, DataTypeFunctions, DataTypeBuilder, TypedData}` all
  moved to `typed_data` module, `r_typed_data` module removed. This should only
  affect `DataTypeBuilder` as it was the only one not exported at the crate
  root.
- `gc::adjust_memory_usage`'s argument changed to `isize`, rather than `i32` or
  `i64` depending on pointer width.
- The `IntoValue` trait is now used instead of `Into<Value>` for converting to
  Ruby types.
- `IntoId`, `IntoRString`, and `IntoSymbol` are used instead of `Into<Id>`,
  `Into<RString>`, and `Into<Symbol>`.
- `use magnus::prelude::*` will now import traits anonymously.
- `EncodingCapable`, `Module`, `Class`, and `Object` traits can no longer be
  implemented by user code.
- The `wb_protected` flag is automatically set for data wrapped in a Ruby
  object when `mark` is not set.

### Deprecated
- `RString::append` (use `RString::buf_append`).
- `Error::runtime_error` (use `Error::new(exception::runtime_error(), msg)`).
- Implementations of `Into<Value>` (use `IntoValue`).

### Removed
- `DataTypeBuilder::free_immediatly` (use `free_immediately`).
- `From<&str> for RString` / `Into<RString> for &str`.
- `From<String> for RString` / `Into<RString> for String`.
- `From<&str> for Symbol` / `Into<Symbol> for &str`.
- `From<String> for Symbol` / `Into<Symbol> for String`.
- `From<&str> for StaticSymbol` / `Into<StaticSymbol> for &str`.
- `From<String> for StaticSymbol` / `Into<StaticSymbol> for String`.
- `From<&str> for Id` / `Into<Id> for &str`.
- `From<String> for Id` / `Into<Id> for String`.
- Internal `debug_assert_value!()` macro no longer public.

### Fixed
- Missing `ReprValue` implementation for `RStruct`.

## [0.4.4] - 2022-12-24
### Added
- `Class::undef_alloc_func`, a function to remove a class' allocator function.

### Fixed
- 'wrapped' structs from `#[wrap]` and `#[derive(TypedData)]` macros will not
  generate `warning: undefining the allocator of T_DATA class` under Ruby 3.2

## [0.4.3] - 2022-12-07
### Fixed
- `gc::mark_slice` was skipping the last element of the slice.

## [0.4.2] - 2022-11-30
### Fixed
- Removed errant `dbg!()`.

## [0.4.1] - 2022-11-29
### Fixed
- `scan_args::get_kwargs` error/segfault when leading optional args were not
  provided, due to trying to convert the type of the missing value.

## [0.4.0] - 2022-11-19
### Added
- `Value::funcall_with_block`.
- impl `TryConvert` for `Exception` and `ExceptionClass`.
- `Class` trait (implemented for `RClass` and `ExceptionClass`).
- `define_error` and `Module::define_error` helpers for defining an Exception
  Class.
- `RTypedData::wrap` and `RTypedData::get` inherent methods for wrapping Rust
  types in Ruby objects.
- Support for Ruby 3.2 preview.
- Support for mswin platform (msvc) on Windows with Ruby 3.2 (in addition to
  the mingw support previously available for all Ruby versions on Windows).

### Changed
- Switched to rb-sys for low level bindings.
- Rust types wrapped in Ruby objects must be `Send`.
- Only function pointers (fn or non-capturing closure) are accepted as argument
  for `Value::block_call`. Use `Proc::from_fn` + `Value::funcall_with_block`
  for closures that capture variables.
- `Proc::new` only accepts a function pointer, use `Proc::from_fn` for closures
  that capture variables.
- `ExceptionClass::default()` now returns `StandardError` rather than
  `RuntimeError`.
- `TryConvert` now takes `Value` by value (rather than a reference).

### Deprecated
- `DataTypeBuilder::free_immediatly` (use `free_immediately`).
- `free_immediatly` attribute in `wrap` macro (use `free_immediately`).
- `free_immediatly` in `magnus` attribute of `derive(TypedData)` macro
  (use `free_immediately`).

### Removed
- `String::encode_utf8`, use `r_string.conv_enc(RbEncoding::utf8())` instead.
- `Value::leak`, use `gc::register_mark_object` instead.
- `define_global_variable` (use `define_variable`).

### Fixed
- Memory leak of the message when returning an `Error` to raise an exception.
- `Flonum` support disabled for Ruby built with USE_FLONUM=0 (e.g. 32 bit
  systems).
- Correct spelling of `free_immediatly` (to `free_immediately`) in the
  `DataTypeBuilder` struct, and `wrap` and `derive(TypedData)` macros.

### Security
- `printf`-style format strings no longer interpreted in error messages when
  automatically raised as Ruby exceptions.

## [0.3.2] - 2022-05-29

### Fixed
- Better error output from build script when `ruby` can't be found or errors.
- Fixed crash in `Proc::new` and `Value::block_call` when the proc was stored
  and called later.

## [0.3.1] - 2022-05-21

### Fixed
- Integer overflow in Ruby Float to f64 conversion

## [0.3.0] - 2022-05-18
### Added
- `RString::new_shared` and `RString::new_frozen`.
- `encoding` module, including `encoding::Index` and `RbEncoding` types.
- `RString::enc_coderange` and related methods.
- `RString::codepoints` and `RString::char_bytes` iterators over string
  contents.
- The following methods for `RArray`: `dup`, `concat`, `plus`, `delete`,
  `delete_at`, `resize`, `reverse`, `rotate`, and `sort`.
- New methods for `RString`: `enc_new`, `len`, `length`, and `is_empty`.
- `RHash` gains the methods `delete` and `clear`.
- `require`, `current_receiver`, `call_super`, and `define_global_const`
  functions.
- `Object::singleton_class` and `Object::extend_object`.
- `Proc::new`, `Proc::arity`, and `Proc::is_lambda`.
- `superclass` and `name` methods for `RClass`.
- `scan_args::check_arity`.
- Methods for `Module`: `include_module`, `prepend_module`, `const_set`,
  `ancestors`, `define_attr`, and `define_alias`.
- `rb-sys-interop` feature to use low level bindings from rb-sys, and `rb_sys`
  module to expose functions for working with rb-sys.
- Added `gc::register_mark_object`, `gc::register_address`,
  `gc::unregister_address`, `gc::count`, `gc::stat`, and `gc::all_stats`.
- `Error::iter_break`.
- `StaticSymbol::check` and `Id::check` to check if a symbol exists.

### Changed
- `RArray::cat`, `RArray::from_slice`, and `gc::mark_slice` will accept a
  slice of any Ruby type as an argument, rather than only a slice of `Value`.
  This may change type inference rules such that things like
  `RArray::from_slice(&[1.into()])` will no longer work. Use
  `RArray::from_slice(&[Value::from(1)])` instead.
- Similar to above, `gc::location` will accept any Ruby type as an argument.
- `BoxValue` can hold any Ruby type, not just `Value`.
- Improved performance for conversion between Ruby floats/integers and Rust
  types.
- The parameters to the closure passed to `RHash::foreach` will now be
  automatically converted from `Value` to Rust types.
- `Module::define_method`, `Module::define_private_method`,
  `Module::define_protected_method`, `RModule::define_singleton_method`, and
  `Object::define_singleton_method` all return `Result<(), Error>` rather than
  `()` as they may fail in the unusual case that the receiver is frozen.

### Deprecated
- `String::encode_utf8`, use `r_string.conv_enc(RbEncoding::utf8())` instead.
- `Value::leak`, use `gc::register_mark_object` instead.
- `define_global_variable` (use `define_variable`) to better match Ruby C API
  naming.
- `Exception::backtrace`, use `ex.funcall("backtrace", ())` instead.

### Removed
- `error::protect` removed as it should not be needed when using Magnus. For
  use with rb-sys enable the `rb-sys-interop` feature and use
  `magnus::rb_sys::protect`.
- `Qfalse::new`, `Qnil::new`, `Qtrue::new`, `Qundef::new` (use
  QFALSE/QNIL/QTRUE/QUNDEF).
- Functions for generating an `Error` with a specific Ruby type. E.g.
  `Error::type_error("...")`, use `Error::new(exception::type_error(), "...")`.

### Fixed
- creating a `StaticSymbol` from a `&str` with characters outside the ASCII
  range.
- panicking in any of the functions of `DataTypeFunctions` will abort the
  process to avoid undefined behaviour.
- panicking in the closure passed to `RHash::foreach` won't result in undefined
  behaviour.

## [0.2.1] - 2022-04-03

### Fixed
- Fixed compilation error in `method!` and `function!` macros with arity
  argument of 5.

## [0.2.0] - 2022-03-31
### Added
- Functions in `class`, `module`, and `error` modules to access built-in
  classes/modules.
- Many doc examples.
- `RArray::len`, `RArray::includes`, `RArray::join`, `RArray::is_shared`,
  `RArray::replace`, and `RArray::subseq`.
- Implement `From<&str>` and `From<String>` for `RString`.
- Support for `Range`.
- Pre-built bindings for Ruby 3.1 on Windows.
- Support calling Ruby methods with Rust closure as a Ruby block.
- `Class::new` and `Module::new` for creating anonymous classes/modules.
- `r_string!` macro to create Ruby string from a `str` literal.
- `Value::equal` and `Value::eql` for object equality.
- `Value::respond_to` and `Value::check_funcall` for conditionally calling Ruby
  methods only when they are defined.
- `scan_args` and `get_kwargs` for complex argument parsing.

### Changed
- `Qundef::to_value` now marked `unsafe`.
- `RArray::cat`, `RArray::push`, `RArray::unshift`, and `RArray::store` now
  return `Result<(), Error>`.
- `eval!` macro uses anonymous (rather than caller's) binding.

### Deprecated
- `Qfalse::new`, `Qnil::new`, `Qtrue::new`, `Qundef::new` (use
  QFALSE/QNIL/QTRUE/QUNDEF).
- Functions for generating an `Error` with a specific Ruby type. E.g.
  `Error::type_error("...")` is now `Error::new(exception::type_error(), "...")`
- `Binding::new`. This will be removed in the future as the underlying
  `rb_binding_new` will not function as of Ruby 3.2.

### Fixed
- Converting Ruby integers to `isize`/`i64`/`usize`/`u64` on Windows.
- Edge case where static symbol created after a dynamic symbol with the same
  name wouldn't be detected as static.
- Many `RArray` methods now correctly protect from exceptions (instead
  returning `Result<_, Error>` when an exception occurs).

## [0.1.0] - 2022-02-25
### Added
- Support for most core classes, `String`, `Symbol`, `Integer`, `Float`,
  `Array`, `Hash` and more.
- Defining Rust methods as Ruby functions.
- Calling Ruby methods from Rust.
- Automatic type conversion between Rust and Ruby types.
- Conversion from Ruby exceptions to Rust Results and visa versa.
- Support for wrapping custom Rust structs as Ruby objects.
- `Enumerator` as a iterator.
- `yield` to Ruby blocks.
- `#[init]` macro to mark init function to load extension with `require`.
- Pre-built bindings for Ruby 2.6 - 3.1 on common platforms, build-time
  generated bindings otherwise.

[Unreleased]: https://github.com/matsadler/magnus/compare/0.6.4...0.6
[0.6.3]: https://github.com/matsadler/magnus/compare/0.6.3...0.6.4
[0.6.2]: https://github.com/matsadler/magnus/compare/0.6.2...0.6.3
[0.6.2]: https://github.com/matsadler/magnus/compare/0.6.1...0.6.2
[0.6.1]: https://github.com/matsadler/magnus/compare/0.6.0...0.6.1
[0.6.0]: https://github.com/matsadler/magnus/compare/0.5.3...0.6.0
[0.5.3]: https://github.com/matsadler/magnus/compare/0.5.2...0.5.3
[0.5.2]: https://github.com/matsadler/magnus/compare/0.5.1...0.5.2
[0.5.1]: https://github.com/matsadler/magnus/compare/0.5.0...0.5.1
[0.5.0]: https://github.com/matsadler/magnus/compare/0.4.4...0.5.0
[0.4.4]: https://github.com/matsadler/magnus/compare/0.4.3...0.4.4
[0.4.3]: https://github.com/matsadler/magnus/compare/0.4.2...0.4.3
[0.4.2]: https://github.com/matsadler/magnus/compare/0.4.1...0.4.2
[0.4.1]: https://github.com/matsadler/magnus/compare/0.4.0...0.4.1
[0.4.0]: https://github.com/matsadler/magnus/compare/0.3.2...0.4.0
[0.3.2]: https://github.com/matsadler/magnus/compare/0.3.1...0.3.2
[0.3.1]: https://github.com/matsadler/magnus/compare/0.3.0...0.3.1
[0.3.0]: https://github.com/matsadler/magnus/compare/0.2.1...0.3.0
[0.2.1]: https://github.com/matsadler/magnus/compare/0.2.0...0.2.1
[0.2.0]: https://github.com/matsadler/magnus/compare/0.1.0...0.2.0
[0.1.0]: https://github.com/matsadler/magnus/tree/0.1.0