1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
//! Definitions for Ruby's special constants.
//!
//! Makes it easier to reference important Ruby constants, without havign to dig
//! around in bindgen's output.
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
use crate::{ruby_special_consts, VALUE};
pub const Qfalse: ruby_special_consts = ruby_special_consts::RUBY_Qfalse;
pub const Qtrue: ruby_special_consts = ruby_special_consts::RUBY_Qtrue;
pub const Qnil: ruby_special_consts = ruby_special_consts::RUBY_Qnil;
pub const Qundef: ruby_special_consts = ruby_special_consts::RUBY_Qundef;
pub const IMMEDIATE_MASK: ruby_special_consts = ruby_special_consts::RUBY_IMMEDIATE_MASK;
pub const FIXNUM_FLAG: ruby_special_consts = ruby_special_consts::RUBY_FIXNUM_FLAG;
pub const FLONUM_MASK: ruby_special_consts = ruby_special_consts::RUBY_FLONUM_MASK;
pub const FLONUM_FLAG: ruby_special_consts = ruby_special_consts::RUBY_FLONUM_FLAG;
pub const SYMBOL_FLAG: ruby_special_consts = ruby_special_consts::RUBY_SYMBOL_FLAG;
#[allow(clippy::from_over_into)]
impl Into<VALUE> for ruby_special_consts {
fn into(self) -> VALUE {
self as VALUE
}
}
/// Emulates Ruby's "if" statement.
///
/// @param[in] obj An arbitrary ruby object.
/// @retval false `obj` is either ::RUBY_Qfalse or ::RUBY_Qnil.
/// @retval true Anything else.
///
/// ```
/// use rb_sys::special_consts::*;
///
/// assert!(!TEST(Qfalse));
/// assert!(!TEST(Qnil));
/// assert!(TEST(Qtrue));
/// ```
#[inline(always)]
pub fn TEST<T: Into<VALUE>>(obj: T) -> bool {
(obj.into() & !(Qnil as VALUE)) != 0
}
/// Checks if the given object is nil.
///
/// @param[in] obj An arbitrary ruby object.
/// @retval true `obj` is ::RUBY_Qnil.
/// @retval false Anything else.
///
/// ```
/// use rb_sys::special_consts::*;
///
/// assert!(NIL_P(Qnil));
/// assert!(!NIL_P(Qtrue));
/// ```
#[inline(always)]
pub fn NIL_P<T: Into<VALUE>>(obj: T) -> bool {
obj.into() == (Qnil as VALUE)
}
/// Checks if the given object is a so-called Fixnum.
///
/// @param[in] obj An arbitrary ruby object.
/// @retval true `obj` is a Fixnum.
/// @retval false Anything else.
/// @note Fixnum was a thing in the 20th century, but it is rather an
/// implementation detail today.
#[inline(always)]
pub fn FIXNUM_P<T: Into<VALUE>>(obj: T) -> bool {
(obj.into() & FIXNUM_FLAG as VALUE) != 0
}
/// Checks if the given object is a static symbol.
///
/// @param[in] obj An arbitrary ruby object.
/// @retval true `obj` is a static symbol
/// @retval false Anything else.
/// @see RB_DYNAMIC_SYM_P()
/// @see RB_SYMBOL_P()
/// @note These days there are static and dynamic symbols, just like we
/// once had Fixnum/Bignum back in the old days.
pub fn STATIC_SYM_P<T: Into<VALUE>>(obj: T) -> bool {
(obj.into() & 0xff) == SYMBOL_FLAG as VALUE
}
/// Checks if the given object is a so-called Flonum.
///
/// @param[in] obj An arbitrary ruby object.
/// @retval true `obj` is a Flonum.
/// @retval false Anything else.
/// @see RB_FLOAT_TYPE_P()
/// @note These days there are Flonums and non-Flonum floats, just like we
/// once had Fixnum/Bignum back in the old days.
#[inline(always)]
pub fn FLONUM_P<T: Into<VALUE>>(obj: T) -> bool {
(obj.into() & (FLONUM_MASK as VALUE)) == FLONUM_FLAG as VALUE
}
/// Checks if the given object is an immediate i.e. an object which has no
/// corresponding storage inside of the object space.
///
/// @param[in] obj An arbitrary ruby object.
/// @retval true `obj` is a Flonum.
/// @retval false Anything else.
/// @see RB_FLOAT_TYPE_P()
/// @note The concept of "immediate" is purely C specific.
#[inline(always)]
pub fn IMMEDIATE_P<T: Into<VALUE>>(obj: T) -> bool {
obj.into() & (IMMEDIATE_MASK as VALUE) != 0
}
/// Checks if the given object is of enum ::ruby_special_consts.
///
/// @param[in] obj An arbitrary ruby object.
/// @retval true `obj` is a special constant.
/// @retval false Anything else.
///
/// ```
/// use rb_sys::special_consts::*;
///
/// assert!(SPECIAL_CONST_P(Qnil));
/// assert!(SPECIAL_CONST_P(Qtrue));
/// assert!(SPECIAL_CONST_P(Qfalse));
/// ```
#[inline(always)]
pub fn SPECIAL_CONST_P<T: Into<VALUE>>(obj: T) -> bool {
let value: VALUE = obj.into();
let is_immediate = value & (IMMEDIATE_MASK as VALUE) != 0;
let test = (value & !(Qnil as VALUE)) != 0;
is_immediate || !test
}