rutie 0.12.1

The tie between Ruby and Rust.
Documentation
use crate::rubysys::{
    constant,
    types::{c_char, c_int, c_void, size_t, InternalValue, Value},
};

#[cfg_attr(rutie_dllimport, link(name = "rutie_ruby"))]
extern "C" {
    // void *
    // rb_check_typeddata(VALUE obj, const rb_data_type_t *data_type)
    pub fn rb_check_typeddata(object: Value, data_type: *const RbDataType) -> *mut c_void;
    // int
    // rb_typeddata_inherited_p(const rb_data_type_t *child, const rb_data_type_t *parent)
    pub fn rb_typeddata_inherited_p(child: *const RbDataType, parent: *const RbDataType) -> c_int;
    // int
    // rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
    pub fn rb_typeddata_is_kind_of(object: Value, data_type: *const RbDataType) -> c_int;
    // VALUE
    // rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type)
    pub fn rb_data_typed_object_wrap(
        klass: Value,
        data: *mut c_void,
        data_type: *const RbDataType,
    ) -> Value;
}

#[repr(C)]
pub struct RbDataTypeFunction {
    pub dmark: Option<extern "C" fn(*mut c_void)>,
    pub dfree: Option<extern "C" fn(*mut c_void)>,
    pub dsize: Option<extern "C" fn(*const c_void) -> size_t>,
    // `dcompact` and `reserved[1]` in Ruby 3's headers: `reserved[0]` holds
    // the compaction callback, a `void (*)(void *)`, or null.
    pub reserved: [*mut c_void; 2],
}

unsafe impl Send for RbDataTypeFunction {}
unsafe impl Sync for RbDataTypeFunction {}

// `RbDataType::flags` (`RUBY_TYPED_*`).
//
// `dfree` runs during the sweep instead of being deferred.
pub const RUBY_TYPED_FREE_IMMEDIATELY: InternalValue = 1;
// Ruby 3.3+: the struct may be embedded in the object's slot.
#[cfg(ruby_gte_3_3)]
pub const RUBY_TYPED_EMBEDDABLE: InternalValue = 2;
// Frozen objects of this type are Ractor-shareable.
pub const RUBY_TYPED_FROZEN_SHAREABLE: InternalValue = constant::FL_SHAREABLE as InternalValue;
// `dmark` and writes to the struct's `VALUE`s use write barriers.
pub const RUBY_TYPED_WB_PROTECTED: InternalValue = constant::FL_WB_PROTECTED as InternalValue;
// Ruby 3.3+: `dmark` is a `RUBY_REFERENCES` list of offsets, not a function.
#[cfg(ruby_gte_3_3)]
pub const RUBY_TYPED_DECL_MARKING: InternalValue = constant::FL_USER_2 as InternalValue;

#[repr(C)]
pub struct RbDataType {
    pub wrap_struct_name: *const c_char,
    pub function: RbDataTypeFunction,
    pub parent: *const RbDataType,
    pub data: *mut c_void,
    pub flags: Value,
}

unsafe impl Send for RbDataType {}
unsafe impl Sync for RbDataType {}