artichoke_core/
types.rs

1//! Ruby and Rust type mappings.
2
3use core::fmt;
4
5/// Classes of Rust types.
6#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
7pub enum Rust {
8    /// Rust `bool` type.
9    Bool,
10    /// Rust `Vec<u8>` type.
11    Bytes,
12    /// Rust float type.
13    ///
14    /// Float width is dependent on interpreter implementation and architecture.
15    Float,
16    /// Rust `HashMap<K, V>` type.
17    Map,
18    /// Arbitrary Rust struct type.
19    Object,
20    /// Rust signed integer type.
21    ///
22    /// Int width is dependent on interpreter implementation and architecture.
23    SignedInt,
24    /// Rust `String` type.
25    String,
26    /// Rust unsigned integer type.
27    ///
28    /// Int width is dependent on interpreter implementation and architecture.
29    UnsignedInt,
30    /// Rust `Vec<T>` type.
31    Vec,
32}
33
34impl fmt::Display for Rust {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        f.write_str("Rust ")?;
37        match self {
38            Self::Bool => f.write_str("bool"),
39            Self::Bytes => f.write_str("Vec<u8>"),
40            Self::Float => f.write_str("f64"),
41            Self::Map => f.write_str("HashMap"),
42            Self::Object => f.write_str("Heap-allocated object"),
43            Self::SignedInt => f.write_str("i64"),
44            Self::String => f.write_str("String"),
45            Self::UnsignedInt => f.write_str("u64"),
46            Self::Vec => f.write_str("Vec<Value>"),
47        }
48    }
49}
50
51/// Classes of Ruby types.
52#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
53pub enum Ruby {
54    /// Ruby `Array` type.
55    Array,
56    /// Ruby `TrueClass` and `FalseClass` type.
57    Bool,
58    /// Ruby `Class` type.
59    Class,
60    /// FFI type for a borrowed C pointer.
61    CPointer,
62    /// FFI type for an owned C pointer.
63    Data,
64    /// Ruby `Exception` type.
65    Exception,
66    /// Ruby `Fiber` type.
67    Fiber,
68    /// Ruby `Fixnum` type.
69    ///
70    /// `Fixnum` is a type of `Integer` which represents numbers from
71    /// `[-u64::MAX, us64::MAX]`. `Fixnum`s have a special algorithm for
72    /// object IDs: `2 * self - 1`.
73    Fixnum,
74    /// Ruby `Float` type.
75    Float,
76    /// Ruby `Hash` type.
77    ///
78    /// Similar to a [`HashMap`], but iterates by insertion order.
79    ///
80    /// [`HashMap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html
81    Hash,
82    /// Internal type for non-heap allocated structs.
83    InlineStruct,
84    /// Ruby `Module` type.
85    Module,
86    /// Ruby `nil` singleton type, the only instance of `NilClass`.
87    Nil,
88    /// Ruby `Object` type.
89    ///
90    /// This type represents instances of classes defined in the Artichoke VM.
91    Object,
92    /// Ruby `Proc` type.
93    ///
94    /// `Proc` is a callable closure that captures lexical scope. `Proc`s can
95    /// be arbitrary arity and may or may not enforce this arity when called.
96    Proc,
97    /// Ruby `Range` type.
98    ///
99    /// Similar to a Rust [iterator](core::iter).
100    Range,
101    /// Internal type for the singleton class of an object.
102    SingletonClass,
103    /// Ruby `String` type.
104    ///
105    /// In Artichoke, `String`s have a limited set of encodings. A `String` can
106    /// be UTF-8, [maybe UTF-8](https://docs.rs/bstr/), or binary.
107    String,
108    /// Ruby `Symbol` type.
109    ///
110    /// An interned `String`. Symbols are never freed by the interpreter.
111    Symbol,
112    /// Unreachable interpreter value. Receiving one of these from the
113    /// interpreter is a bug.
114    Unreachable,
115    /// A special `Value` that is a placeholder for collections that own
116    /// themselves.
117    RecursiveSelfOwnership,
118}
119
120impl Ruby {
121    /// Ruby `Class` name for VM type.
122    #[must_use]
123    pub const fn class_name(self) -> &'static str {
124        match self {
125            Self::Array => "Array",
126            Self::Bool => "Boolean",
127            Self::Class => "Class",
128            Self::CPointer => "C Pointer",
129            Self::Data => "Rust-backed Ruby instance",
130            Self::Exception => "Exception",
131            Self::Fiber => "Fiber",
132            Self::Fixnum => "Integer",
133            Self::Float => "Float",
134            Self::Hash => "Hash",
135            Self::InlineStruct => "Inline Struct",
136            Self::Module => "Module",
137            Self::Nil => "NilClass",
138            Self::Object => "Object",
139            Self::Proc => "Proc",
140            Self::Range => "Range",
141            Self::SingletonClass => "Singleton (anonymous) class",
142            Self::String => "String",
143            Self::Symbol => "Symbol",
144            Self::Unreachable => "internal and unreachable",
145            Self::RecursiveSelfOwnership => "recursive self ownership",
146        }
147    }
148}
149
150impl fmt::Display for Ruby {
151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152        f.write_str("Ruby ")?;
153        f.write_str(self.class_name())?;
154        Ok(())
155    }
156}