artichoke_backend/extn/core/symbol/
mruby.rs

1use std::ffi::CStr;
2
3use crate::extn::core::symbol::{self, trampoline};
4use crate::extn::prelude::*;
5
6const SYMBOL_CSTR: &CStr = c"Symbol";
7static SYMBOL_RUBY_SOURCE: &[u8] = include_bytes!("symbol.rb");
8
9pub fn init(interp: &mut Artichoke) -> InitializeResult<()> {
10    if interp.is_class_defined::<symbol::Symbol>() {
11        return Ok(());
12    }
13
14    let spec = class::Spec::new("Symbol", SYMBOL_CSTR, None, None)?;
15    class::Builder::for_spec(interp, &spec)
16        .add_self_method("all_symbols", symbol_all_symbols, sys::mrb_args_none())?
17        .add_method("==", symbol_equal_equal, sys::mrb_args_req(1))?
18        .add_method("casecmp", symbol_ascii_casecmp, sys::mrb_args_req(1))?
19        .add_method("casecmp?", symbol_unicode_casecmp, sys::mrb_args_req(1))?
20        .add_method("empty?", symbol_empty, sys::mrb_args_none())?
21        .add_method("inspect", symbol_inspect, sys::mrb_args_none())?
22        .add_method("length", symbol_length, sys::mrb_args_none())?
23        .add_method("to_s", symbol_to_s, sys::mrb_args_none())?
24        .define()?;
25    interp.def_class::<symbol::Symbol>(spec)?;
26    interp.eval(SYMBOL_RUBY_SOURCE)?;
27
28    Ok(())
29}
30
31unsafe extern "C-unwind" fn symbol_all_symbols(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
32    mrb_get_args!(mrb, none);
33    unwrap_interpreter!(mrb, to => guard);
34    let result = trampoline::all_symbols(&mut guard);
35    match result {
36        Ok(value) => value.inner(),
37        Err(exception) => {
38            // SAFETY: only Copy objects remain on the stack
39            unsafe { error::raise(guard, exception) }
40        }
41    }
42}
43
44unsafe extern "C-unwind" fn symbol_equal_equal(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
45    let other = mrb_get_args!(mrb, required = 1);
46    unwrap_interpreter!(mrb, to => guard);
47    let sym = Value::from(slf);
48    let other = Value::from(other);
49    let result = trampoline::equal_equal(&mut guard, sym, other);
50    match result {
51        Ok(value) => value.inner(),
52        Err(exception) => {
53            // SAFETY: only Copy objects remain on the stack
54            unsafe { error::raise(guard, exception) }
55        }
56    }
57}
58
59unsafe extern "C-unwind" fn symbol_ascii_casecmp(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
60    let other = mrb_get_args!(mrb, required = 1);
61    unwrap_interpreter!(mrb, to => guard);
62    let sym = Value::from(slf);
63    let other = Value::from(other);
64    let result = trampoline::ascii_casecmp(&mut guard, sym, other);
65    match result {
66        Ok(value) => value.inner(),
67        Err(exception) => {
68            // SAFETY: only Copy objects remain on the stack
69            unsafe { error::raise(guard, exception) }
70        }
71    }
72}
73
74unsafe extern "C-unwind" fn symbol_unicode_casecmp(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
75    let other = mrb_get_args!(mrb, required = 1);
76    unwrap_interpreter!(mrb, to => guard);
77    let sym = Value::from(slf);
78    let other = Value::from(other);
79    let result = trampoline::unicode_casecmp(&mut guard, sym, other);
80    match result {
81        Ok(value) => value.inner(),
82        Err(exception) => {
83            // SAFETY: only Copy objects remain on the stack
84            unsafe { error::raise(guard, exception) }
85        }
86    }
87}
88
89unsafe extern "C-unwind" fn symbol_empty(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
90    mrb_get_args!(mrb, none);
91    unwrap_interpreter!(mrb, to => guard);
92    let sym = Value::from(slf);
93    let result = trampoline::is_empty(&mut guard, sym);
94    match result {
95        Ok(value) => value.inner(),
96        Err(exception) => {
97            // SAFETY: only Copy objects remain on the stack
98            unsafe { error::raise(guard, exception) }
99        }
100    }
101}
102
103unsafe extern "C-unwind" fn symbol_inspect(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
104    mrb_get_args!(mrb, none);
105    unwrap_interpreter!(mrb, to => guard);
106    let value = Value::from(slf);
107    let result = trampoline::inspect(&mut guard, value);
108    match result {
109        Ok(value) => value.inner(),
110        Err(exception) => {
111            // SAFETY: only Copy objects remain on the stack
112            unsafe { error::raise(guard, exception) }
113        }
114    }
115}
116
117unsafe extern "C-unwind" fn symbol_length(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
118    mrb_get_args!(mrb, none);
119    unwrap_interpreter!(mrb, to => guard);
120    let sym = Value::from(slf);
121    let result = trampoline::length(&mut guard, sym);
122    match result {
123        Ok(value) => value.inner(),
124        Err(exception) => {
125            // SAFETY: only Copy objects remain on the stack
126            unsafe { error::raise(guard, exception) }
127        }
128    }
129}
130
131unsafe extern "C-unwind" fn symbol_to_s(mrb: *mut sys::mrb_state, slf: sys::mrb_value) -> sys::mrb_value {
132    mrb_get_args!(mrb, none);
133    unwrap_interpreter!(mrb, to => guard);
134    let sym = Value::from(slf);
135    let result = trampoline::bytes(&mut guard, sym);
136    match result {
137        Ok(value) => value.inner(),
138        Err(exception) => {
139            // SAFETY: only Copy objects remain on the stack
140            unsafe { error::raise(guard, exception) }
141        }
142    }
143}