1use crate::prelude::*;
2use crate::Type;
3
4#[cfg(any(test, feature = "mocks"))]
5pub mod mock;
6
7#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, EnumAsInner)]
9#[serde(untagged)]
10pub enum Literal {
11    String(String),
13    Boolean(bool),
15    Character(char),
17    Integer(i64),
19    UnsignedInteger(u64),
21    Float(f64),
23    Tuple(Vec<Literal>),
25    Vector(Vec<Literal>),
27    None,
29    Unknown(String)
31}
32
33impl Literal {
34    pub fn is_compatible_with(&self, type_: &Type) -> bool {
36        match self {
37            Literal::String(_) => type_.is_string() | !type_.is_primitive(),
38            Literal::Boolean(_) => type_.is_boolean(),
39            Literal::Character(_) => type_.is_character(),
40            Literal::Integer(_) => type_.is_integer(),
41            Literal::UnsignedInteger(_) => type_.is_unsigned_integer(),
42            Literal::Float(_) => type_.is_float(),
43            Literal::Tuple(_) => type_.is_tuple(),
44            Literal::Vector(_) => type_.is_vector(),
45            Literal::None => false,
46            Literal::Unknown(_) => false
47        }
48    }
49
50    pub fn default_for_type(type_: &Type) -> Self {
51        if type_.is_string() {
52            Self::String(Default::default())
53        } else if type_.is_boolean() {
54            Self::Boolean(false)
55        } else if type_.is_character() {
56            Self::Character('A')
57        } else if type_.is_integer() {
58            Self::Integer(0)
59        } else if type_.is_unsigned_integer() {
60            Self::UnsignedInteger(0)
61        } else if type_.is_float() {
62            Self::Float(0.0)
63        } else {
64            Self::None
65        }
66    }
67}
68
69impl Default for Literal {
70    fn default() -> Self {
71        Self::None
72    }
73}
74
75impl From<&str> for Literal {
76    fn from(value: &str) -> Self {
77        value.to_string().into()
78    }
79}
80
81impl From<String> for Literal {
82    fn from(value: String) -> Self {
83        Self::String(value)
84    }
85}
86
87impl From<bool> for Literal {
88    fn from(value: bool) -> Self {
89        Self::Boolean(value)
90    }
91}
92
93impl From<i32> for Literal {
94    fn from(value: i32) -> Self {
95        Self::Integer(value as i64)
96    }
97}
98
99impl From<i64> for Literal {
100    fn from(value: i64) -> Self {
101        Self::Integer(value)
102    }
103}
104
105impl From<f32> for Literal {
106    fn from(value: f32) -> Self {
107        Self::Float(value as f64)
108    }
109}
110
111impl From<f64> for Literal {
112    fn from(value: f64) -> Self {
113        Self::Float(value)
114    }
115}
116
117impl From<u32> for Literal {
118    fn from(value: u32) -> Self {
119        Self::UnsignedInteger(value as u64)
120    }
121}
122
123impl From<u64> for Literal {
124    fn from(value: u64) -> Self {
125        Self::UnsignedInteger(value)
126    }
127}
128
129impl std::fmt::Display for Literal {
130    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
131        match self {
132            Literal::String(value) => write!(f, "{}", value),
133            Literal::Boolean(value) => write!(f, "{}", value),
134            Literal::Character(value) => write!(f, "{}", value),
135            Literal::Integer(value) => write!(f, "{}", value),
136            Literal::UnsignedInteger(value) => write!(f, "{}", value),
137            Literal::Float(value) => write!(f, "{}", value),
138            Literal::Tuple(values) => {
139                write!(f, "(")?;
140                for (index, value) in values.iter().enumerate() {
141                    if index > 0 {
142                        write!(f, ", ")?;
143                    }
144                    write!(f, "{}", value)?;
145                }
146                write!(f, ")")
147            },
148            Literal::Vector(values) => {
149                write!(f, "[")?;
150                for (index, value) in values.iter().enumerate() {
151                    if index > 0 {
152                        write!(f, ", ")?;
153                    }
154                    write!(f, "{}", value)?;
155                }
156                write!(f, "]")
157            },
158            Literal::None => write!(f, "None"),
159            Literal::Unknown(s) => write!(f, "Unknown({})", s)
160        }
161    }
162}