stainless_script/
object.rs1use crate::class::Class;
2use std::{
3 cmp::Ordering,
4 error::Error,
5 fmt::{Debug, Display},
6 rc::Rc,
7 str::FromStr,
8};
9
10pub trait ObjectFromStr {
13 fn from_str(s: &str) -> Result<Rc<dyn Object>, Box<dyn Error + Send + Sync>>
14 where
15 Self: Sized;
16}
17
18impl<T: 'static + FromStr + Object> ObjectFromStr for T
19where
20 T::Err: 'static + Error + Send + Sync,
21{
22 fn from_str(s: &str) -> Result<Rc<dyn Object>, Box<dyn Error + Send + Sync>> {
23 <Self as FromStr>::from_str(s)
24 .map_err(Into::into)
25 .map(|o| Rc::new(o) as Rc<dyn Object>)
26 }
27}
28
29pub trait ObjectPartialEq {
31 fn eq(&self, other: Rc<dyn Object>) -> bool;
32 fn ne(&self, other: Rc<dyn Object>) -> bool {
33 !self.eq(other)
34 }
35}
36
37pub trait ObjectPartialOrd {
39 fn partial_cmp(&self, other: Rc<dyn Object>) -> Option<Ordering>;
40 fn lt(&self, other: Rc<dyn Object>) -> bool {
41 matches!(self.partial_cmp(other), Some(Ordering::Less))
42 }
43 fn le(&self, other: Rc<dyn Object>) -> bool {
44 matches!(
45 self.partial_cmp(other),
46 Some(Ordering::Less | Ordering::Equal)
47 )
48 }
49 fn gt(&self, other: Rc<dyn Object>) -> bool {
50 matches!(self.partial_cmp(other), Some(Ordering::Greater))
51 }
52 fn ge(&self, other: Rc<dyn Object>) -> bool {
53 matches!(
54 self.partial_cmp(other),
55 Some(Ordering::Greater | Ordering::Equal)
56 )
57 }
58}
59
60pub trait ObjectEq: ObjectPartialEq {}
62
63pub trait ObjectOrd: ObjectEq + ObjectPartialOrd {
65 fn cmp(&self, other: Rc<dyn Object>) -> Ordering;
66}
67
68pub trait Object:
71 Display + Debug + ObjectFromStr + ObjectPartialEq + ObjectPartialOrd + ObjectEq + ObjectOrd
72{
73 fn class(&self) -> Class;
74 fn as_string(&self) -> String {
78 self.to_string()
79 }
80 fn as_number(&self) -> f64;
82 fn as_bool(&self) -> bool;
84 fn get_field(&self, _field: Rc<dyn Object>) -> Rc<dyn Object> {
87 unimplemented!()
88 }
89 fn set_field(&mut self, _field: Rc<dyn Object>, _value: Rc<dyn Object>) {
93 unimplemented!()
94 }
95
96 fn cast_to(&self, to: &Class) -> Rc<dyn Object> {
97 if self.class().name == "any" {
98 (to.obj_from_str.unwrap())(&self.as_string()).unwrap()
99 } else {
100 unimplemented!()
101 }
102 }
103}