1use std::fmt;
2
3use rb_sys::ruby_value_type;
4
5use crate::{
6 error::Error,
7 into_value::IntoValue,
8 object::Object,
9 try_convert::TryConvert,
10 value::{
11 private::{self, ReprValue as _},
12 NonZeroValue, ReprValue, Value,
13 },
14 Ruby,
15};
16
17#[derive(Clone, Copy)]
23#[repr(transparent)]
24pub struct RObject(NonZeroValue);
25
26impl RObject {
27 #[inline]
44 pub fn from_value(val: Value) -> Option<Self> {
45 unsafe {
46 (val.rb_type() == ruby_value_type::RUBY_T_OBJECT)
47 .then(|| Self(NonZeroValue::new_unchecked(val)))
48 }
49 }
50}
51
52impl fmt::Display for RObject {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 write!(f, "{}", unsafe { self.to_s_infallible() })
55 }
56}
57
58impl fmt::Debug for RObject {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 write!(f, "{}", self.inspect())
61 }
62}
63
64impl IntoValue for RObject {
65 #[inline]
66 fn into_value_with(self, _: &Ruby) -> Value {
67 self.0.get()
68 }
69}
70
71impl Object for RObject {}
72
73unsafe impl private::ReprValue for RObject {}
74
75impl ReprValue for RObject {}
76
77impl TryConvert for RObject {
78 fn try_convert(val: Value) -> Result<Self, Error> {
79 Self::from_value(val).ok_or_else(|| {
80 Error::new(
81 Ruby::get_with(val).exception_type_error(),
82 format!("no implicit conversion of {} into Object", unsafe {
83 val.classname()
84 },),
85 )
86 })
87 }
88}