use std::ffi::CStr;
use crate::{
prelude::*,
ruby::{self, VALUE},
};
#[inline]
pub unsafe fn eval(script: &CStr) -> AnyObject {
AnyObject::from_raw(ruby::rb_eval_string(script.as_ptr()))
}
#[inline]
pub unsafe fn eval_protected(script: &CStr) -> Result<AnyObject> {
let mut err = 0;
let raw = ruby::rb_eval_string_protect(script.as_ptr(), &mut err);
match err {
0 => Ok(AnyObject::from_raw(raw)),
_ => Err(AnyException::_take_current()),
}
}
#[inline]
pub unsafe fn eval_wrapped(script: &CStr) -> Result<AnyObject> {
let mut err = 0;
let raw = ruby::rb_eval_string_wrap(script.as_ptr(), &mut err);
match err {
0 => Ok(AnyObject::from_raw(raw)),
_ => Err(AnyException::_take_current()),
}
}
pub trait EvalArgs: Sized {
unsafe fn eval_in_object(self, object: impl Into<AnyObject>) -> AnyObject;
unsafe fn eval_in_object_protected(self, object: impl Into<AnyObject>) -> Result<AnyObject>;
unsafe fn eval_in_mixin(self, mixin: impl Mixin) -> AnyObject;
unsafe fn eval_in_mixin_protected(self, mixin: impl Mixin) -> Result<AnyObject>;
}
impl<O: Object> EvalArgs for &[O] {
#[inline]
unsafe fn eval_in_object_protected(self, object: impl Into<AnyObject>) -> Result<AnyObject> {
unsafe fn eval(args: &[AnyObject], object: AnyObject) -> Result<AnyObject> {
crate::protected_no_panic(|| args.eval_in_object(object))
}
eval(AnyObject::convert_slice(self), object.into())
}
#[inline]
unsafe fn eval_in_object(self, object: impl Into<AnyObject>) -> AnyObject {
let raw = ruby::rb_obj_instance_eval(
self.len() as _,
self.as_ptr() as *const VALUE,
object.into().raw(),
);
AnyObject::from_raw(raw)
}
#[inline]
unsafe fn eval_in_mixin_protected(self, mixin: impl Mixin) -> Result<AnyObject> {
unsafe fn eval(args: &[AnyObject], mixin: VALUE) -> Result<AnyObject> {
let raw = crate::protected_no_panic(|| ruby::rb_mod_module_eval(
args.len() as _,
args.as_ptr() as *const VALUE,
mixin,
))?;
Ok(AnyObject::from_raw(raw))
}
eval(AnyObject::convert_slice(self), mixin.raw())
}
#[inline]
unsafe fn eval_in_mixin(self, mixin: impl Mixin) -> AnyObject {
let raw = ruby::rb_mod_module_eval(
self.len() as _,
self.as_ptr() as *const VALUE,
mixin.raw(),
);
AnyObject::from_raw(raw)
}
}
impl EvalArgs for String {
#[inline]
unsafe fn eval_in_object_protected(self, object: impl Into<AnyObject>) -> Result<AnyObject> {
self.as_any_slice().eval_in_object_protected(object)
}
#[inline]
unsafe fn eval_in_object(self, object: impl Into<AnyObject>) -> AnyObject {
self.as_any_slice().eval_in_object(object)
}
#[inline]
unsafe fn eval_in_mixin_protected(self, mixin: impl Mixin) -> Result<AnyObject> {
self.as_any_slice().eval_in_mixin_protected(mixin)
}
#[inline]
unsafe fn eval_in_mixin(self, mixin: impl Mixin) -> AnyObject {
self.as_any_slice().eval_in_mixin(mixin)
}
}
impl EvalArgs for &str {
#[inline]
unsafe fn eval_in_object_protected(self, object: impl Into<AnyObject>) -> Result<AnyObject> {
String::from(self).eval_in_object_protected(object)
}
#[inline]
unsafe fn eval_in_object(self, object: impl Into<AnyObject>) -> AnyObject {
String::from(self).eval_in_object(object)
}
#[inline]
unsafe fn eval_in_mixin_protected(self, mixin: impl Mixin) -> Result<AnyObject> {
String::from(self).eval_in_mixin_protected(mixin)
}
#[inline]
unsafe fn eval_in_mixin(self, mixin: impl Mixin) -> AnyObject {
String::from(self).eval_in_mixin(mixin)
}
}
impl<S: Into<String>, F: Into<String>> EvalArgs for (S, F) {
#[inline]
unsafe fn eval_in_object_protected(self, object: impl Into<AnyObject>) -> Result<AnyObject> {
let (s, f) = self;
[s.into(), f.into()].eval_in_object_protected(object)
}
#[inline]
unsafe fn eval_in_object(self, object: impl Into<AnyObject>) -> AnyObject {
let (s, f) = self;
[s.into(), f.into()].eval_in_object(object)
}
#[inline]
unsafe fn eval_in_mixin_protected(self, mixin: impl Mixin) -> Result<AnyObject> {
let (s, f) = self;
[s.into(), f.into()].eval_in_mixin_protected(mixin)
}
#[inline]
unsafe fn eval_in_mixin(self, mixin: impl Mixin) -> AnyObject {
let (s, f) = self;
[s.into(), f.into()].eval_in_mixin(mixin)
}
}
impl<S, F, L> EvalArgs for (S, F, L)
where
S: Into<String>,
F: Into<String>,
L: Into<Integer>,
{
#[inline]
unsafe fn eval_in_object_protected(self, object: impl Into<AnyObject>) -> Result<AnyObject> {
let (s, f, l) = self;
let s = AnyObject::from(s.into());
let f = AnyObject::from(f.into());
let l = AnyObject::from(l.into());
[s, f, l].eval_in_object_protected(object)
}
#[inline]
unsafe fn eval_in_object(self, object: impl Into<AnyObject>) -> AnyObject {
let (s, f, l) = self;
let s = AnyObject::from(s.into());
let f = AnyObject::from(f.into());
let l = AnyObject::from(l.into());
[s, f, l].eval_in_object(object)
}
#[inline]
unsafe fn eval_in_mixin_protected(self, mixin: impl Mixin) -> Result<AnyObject> {
let (s, f, l) = self;
let s = AnyObject::from(s.into());
let f = AnyObject::from(f.into());
let l = AnyObject::from(l.into());
[s, f, l].eval_in_mixin_protected(mixin)
}
#[inline]
unsafe fn eval_in_mixin(self, mixin: impl Mixin) -> AnyObject {
let (s, f, l) = self;
let s = AnyObject::from(s.into());
let f = AnyObject::from(f.into());
let l = AnyObject::from(l.into());
[s, f, l].eval_in_mixin(mixin)
}
}