artichoke_backend/sys/
mod.rs1#![warn(missing_docs)]
2
3use std::ffi::CStr;
10use std::fmt::{self, Write};
11
12use crate::types::{self, Ruby};
13
14mod args;
15#[allow(
16 missing_debug_implementations,
17 missing_docs,
18 non_camel_case_types,
19 non_upper_case_globals,
20 non_snake_case,
21 trivial_casts,
22 trivial_numeric_casts,
23 unsafe_op_in_unsafe_fn,
24 unused_qualifications,
25 clippy::all,
26 clippy::pedantic,
27 clippy::restriction,
28 reason = "generated code"
29)]
30#[expect(
31 unnecessary_transmutes,
32 reason = "bindgen bitfields codegen under Rust 1.88+ - https://github.com/rust-lang/rust-bindgen/issues/3241"
33)]
34mod ffi {
35 include!(concat!(env!("OUT_DIR"), "/ffi.rs"));
36}
37pub(crate) mod protect;
38
39pub use self::args::*;
40pub use self::ffi::*;
41
42#[must_use]
44pub fn mrb_sys_value_is_nil(value: mrb_value) -> bool {
45 unsafe { ffi::mrb_sys_value_is_nil(value) }
48}
49
50#[must_use]
52pub fn mrb_sys_value_is_false(value: mrb_value) -> bool {
53 unsafe { ffi::mrb_sys_value_is_false(value) }
56}
57
58#[must_use]
60pub fn mrb_sys_value_is_true(value: mrb_value) -> bool {
61 unsafe { ffi::mrb_sys_value_is_true(value) }
64}
65
66#[must_use]
70pub fn mrb_sys_nil_value() -> mrb_value {
71 unsafe { ffi::mrb_sys_nil_value() }
74}
75
76impl Default for mrb_value {
77 fn default() -> Self {
78 mrb_sys_nil_value()
79 }
80}
81
82impl fmt::Debug for mrb_value {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 match types::ruby_from_mrb_value(*self) {
85 Ruby::Nil => f.write_str("nil"),
86 Ruby::Bool if mrb_sys_value_is_true(*self) => f.write_str("true"),
87 Ruby::Bool => f.write_str("false"),
88 Ruby::Fixnum => {
89 let fixnum = unsafe { mrb_sys_fixnum_to_cint(*self) };
91 write!(f, "{fixnum}")
92 }
93 Ruby::Float => {
94 let float = unsafe { mrb_sys_float_to_cdouble(*self) };
96 write!(f, "{float}")
97 }
98 type_tag => write!(f, "<{type_tag}>"),
99 }
100 }
101}
102
103#[must_use]
105pub fn mrb_sys_mruby_version(verbose: bool) -> String {
106 if !verbose {
107 return String::from(env!("CARGO_PKG_VERSION"));
108 }
109
110 let engine = CStr::from_bytes_with_nul(MRUBY_RUBY_ENGINE).unwrap_or(c"unknown");
111 let engine = engine.to_str().unwrap_or("unknown");
112 let version = CStr::from_bytes_with_nul(MRUBY_RUBY_VERSION).unwrap_or(c"0.0.0");
113 let version = version.to_str().unwrap_or("0.0.0");
114
115 let mut out = String::new();
116 out.push_str(engine);
117 out.push(' ');
118 out.push_str(version);
119 out.push_str(" [");
120 out.push_str(env!("CARGO_PKG_VERSION"));
121 out.push(']');
122 out
123}
124
125#[must_use]
136pub fn mrb_sys_state_debug(mrb: *mut mrb_state) -> String {
137 let engine = CStr::from_bytes_with_nul(MRUBY_RUBY_ENGINE).unwrap_or(c"unknown");
138 let engine = engine.to_str().unwrap_or("unknown");
139 let version = CStr::from_bytes_with_nul(MRUBY_RUBY_VERSION).unwrap_or(c"0.0.0");
140 let version = version.to_str().unwrap_or("0.0.0");
141
142 let mut debug = String::new();
143 let _ = write!(
150 &mut debug,
151 "{engine} {version} (v{MRUBY_RELEASE_MAJOR}.{MRUBY_RELEASE_MINOR}.{MRUBY_RELEASE_TEENY}) interpreter at {mrb:p}"
152 );
153 debug
154}
155
156#[cfg(test)]
157mod tests {
158 use crate::test::prelude::*;
159
160 #[test]
161 fn interpreter_debug() {
162 let mut interp = interpreter();
165 unsafe {
167 let mrb = interp.mrb.as_mut();
168 let debug = sys::mrb_sys_state_debug(mrb);
169 assert_eq!(debug, format!("mruby 3.2 (v3.2.0) interpreter at {:p}", &*mrb));
170 };
171 }
172}