simple_expressions/types/
primitive.rs1use crate::types::error::{Error, Result};
2
3#[derive(Debug, Clone, PartialEq)]
4pub enum Primitive {
5 Int(i64),
6 Float(f64),
7 Str(String),
8 Bool(bool),
9}
10
11impl Primitive {
12 pub fn as_bool(&self) -> Option<bool> {
13 self.coerce_bool()
14 }
15 pub fn as_int(&self) -> Option<i64> {
16 if let Primitive::Int(i) = self { Some(*i) } else { None }
17 }
18 pub fn as_float(&self) -> Option<f64> {
19 if let Primitive::Float(f) = self { Some(*f) } else { None }
20 }
21 pub fn as_str(&self) -> String {
22 self.as_str_lossy()
23 }
24
25 pub fn coerce_bool(&self) -> Option<bool> {
27 match self {
28 Primitive::Int(i) => Some(*i != 0),
29 Primitive::Float(f) => Some(*f != 0.0),
30 Primitive::Str(s) if s == "true" || s == "false" => Some(s == "true"),
31 Primitive::Bool(b) => Some(*b),
32 _ => None,
33 }
34 }
35 pub fn to_float_lossy(&self) -> Option<f64> {
36 match self {
37 Primitive::Float(f) => Some(*f),
38 Primitive::Int(i) => Some(*i as f64),
39 _ => None,
40 }
41 }
42 pub fn as_str_lossy(&self) -> String {
43 match self {
44 Primitive::Str(s) => s.clone(),
45 Primitive::Int(i) => i.to_string(),
46 Primitive::Float(f) => f.to_string(),
47 Primitive::Bool(b) => b.to_string(),
48 }
49 }
50}
51
52impl From<i64> for Primitive {
53 fn from(v: i64) -> Self {
54 Primitive::Int(v)
55 }
56}
57impl From<f64> for Primitive {
58 fn from(v: f64) -> Self {
59 Primitive::Float(v)
60 }
61}
62impl From<bool> for Primitive {
63 fn from(v: bool) -> Self {
64 Primitive::Bool(v)
65 }
66}
67impl From<String> for Primitive {
68 fn from(v: String) -> Self {
69 Primitive::Str(v)
70 }
71}
72impl From<&str> for Primitive {
73 fn from(v: &str) -> Self {
74 Primitive::Str(v.to_string())
75 }
76}
77
78impl TryFrom<Primitive> for i64 {
79 type Error = Error;
80 fn try_from(p: Primitive) -> Result<Self> {
81 if let Primitive::Int(i) = p { Ok(i) } else { Err(Error::TypeMismatch("expected int".into())) }
82 }
83}
84impl TryFrom<Primitive> for f64 {
85 type Error = Error;
86 fn try_from(p: Primitive) -> Result<Self> {
87 if let Primitive::Float(f) = p { Ok(f) } else { Err(Error::TypeMismatch("expected float".into())) }
88 }
89}
90impl TryFrom<Primitive> for bool {
91 type Error = Error;
92 fn try_from(p: Primitive) -> Result<Self> {
93 if let Primitive::Bool(b) = p { Ok(b) } else { Err(Error::TypeMismatch("expected bool".into())) }
94 }
95}
96impl TryFrom<Primitive> for String {
97 type Error = Error;
98 fn try_from(p: Primitive) -> Result<Self> {
99 if let Primitive::Str(s) = p { Ok(s) } else { Err(Error::TypeMismatch("expected string".into())) }
100 }
101}