Skip to main content

ruby_types/
lib.rs

1//! Ruby types for Rusty Ruby
2//!
3//! This crate provides core Ruby value and error types for the Rusty Ruby ecosystem.
4
5#![warn(missing_docs)]
6
7/// Ruby value type
8#[derive(Debug, Clone, PartialEq)]
9pub enum RubyValue {
10    /// Nil value
11    Nil,
12    /// Boolean value
13    Boolean(bool),
14    /// Integer value
15    Integer(i32),
16    /// Float value
17    Float(f64),
18    /// String value
19    String(String),
20    /// Symbol value
21    Symbol(String),
22    /// Array value
23    Array(Vec<RubyValue>),
24    /// Hash value
25    Hash(std::collections::HashMap<String, RubyValue>),
26    /// Object value
27    Object(String, std::collections::HashMap<String, RubyValue>),
28}
29
30impl RubyValue {
31    /// Check if value is nil
32    pub fn is_nil(&self) -> bool {
33        matches!(self, RubyValue::Nil)
34    }
35
36    /// Convert value to i32
37    pub fn to_i32(&self) -> i32 {
38        match self {
39            RubyValue::Integer(i) => *i,
40            RubyValue::Float(f) => *f as i32,
41            RubyValue::Boolean(b) => {
42                if *b {
43                    1
44                }
45                else {
46                    0
47                }
48            }
49            _ => 0,
50        }
51    }
52
53    /// Convert value to f64
54    pub fn to_f64(&self) -> f64 {
55        match self {
56            RubyValue::Float(f) => *f,
57            RubyValue::Integer(i) => *i as f64,
58            RubyValue::Boolean(b) => {
59                if *b {
60                    1.0
61                }
62                else {
63                    0.0
64                }
65            }
66            _ => 0.0,
67        }
68    }
69
70    /// Convert value to bool
71    pub fn to_bool(&self) -> bool {
72        match self {
73            RubyValue::Nil => false,
74            RubyValue::Boolean(b) => *b,
75            RubyValue::Integer(i) => *i != 0,
76            RubyValue::Float(f) => *f != 0.0,
77            _ => true,
78        }
79    }
80
81    /// Convert value to string
82    pub fn to_string(&self) -> String {
83        match self {
84            RubyValue::String(s) => s.clone(),
85            RubyValue::Symbol(s) => s.clone(),
86            RubyValue::Integer(i) => i.to_string(),
87            RubyValue::Float(f) => f.to_string(),
88            RubyValue::Boolean(b) => b.to_string(),
89            RubyValue::Nil => "nil".to_string(),
90            _ => format!("{:?}", self),
91        }
92    }
93}
94
95/// Ruby error type
96#[derive(Debug, Clone, PartialEq)]
97pub enum RubyError {
98    /// Method not found error
99    MethodNotFound(String),
100    /// Class not found error
101    ClassNotFound(String),
102    /// Lexical analysis error
103    LexicalError(String),
104    /// Syntax analysis error
105    SyntaxError(String),
106    /// Runtime error
107    RuntimeError(String),
108    /// Type error
109    TypeError(String),
110    /// Argument error
111    ArgumentError(String),
112}
113
114impl std::fmt::Display for RubyError {
115    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
116        match self {
117            RubyError::MethodNotFound(name) => write!(f, "Method not found: {}", name),
118            RubyError::ClassNotFound(name) => write!(f, "Class not found: {}", name),
119            RubyError::LexicalError(msg) => write!(f, "Lexical error: {}", msg),
120            RubyError::SyntaxError(msg) => write!(f, "Syntax error: {}", msg),
121            RubyError::RuntimeError(msg) => write!(f, "Runtime error: {}", msg),
122            RubyError::TypeError(msg) => write!(f, "Type error: {}", msg),
123            RubyError::ArgumentError(msg) => write!(f, "Argument error: {}", msg),
124        }
125    }
126}
127
128impl std::error::Error for RubyError {}
129
130/// Ruby result type
131pub type RubyResult<T> = std::result::Result<T, RubyError>;