1use std::convert::From;
4use std::fmt;
5use std::fmt::{Display, Formatter};
6use std::rc::Rc;
7use std::string::ToString;
8
9use crate::error;
10
11#[derive(PartialEq, Debug, Clone)]
13pub enum Val {
14 Empty,
15 Boolean(bool),
16 Int(i64),
17 Float(f64),
18 Str(String),
19 List(Vec<Rc<Val>>),
20 Tuple(Vec<(String, Rc<Val>)>),
21 Env(Vec<(String, String)>),
22}
23
24impl Val {
25 pub fn type_name(&self) -> String {
27 match self {
28 &Val::Empty => "EmptyValue".to_string(),
29 &Val::Boolean(_) => "Boolean".to_string(),
30 &Val::Int(_) => "Integer".to_string(),
31 &Val::Float(_) => "Float".to_string(),
32 &Val::Str(_) => "String".to_string(),
33 &Val::List(_) => "List".to_string(),
34 &Val::Tuple(_) => "Tuple".to_string(),
35 &Val::Env(_) => "Env".to_string(),
36 }
37 }
38
39 pub fn type_equal(&self, target: &Self) -> bool {
41 enum_type_equality!(
42 self,
43 target,
44 &Val::Empty,
45 &Val::Boolean(_),
46 &Val::Int(_),
47 &Val::Float(_),
48 &Val::Str(_),
49 &Val::List(_),
50 &Val::Tuple(_),
51 &Val::Env(_)
52 )
53 }
54
55 pub fn equal(&self, target: &Self) -> Result<bool, error::BuildError> {
56 match (self, target) {
58 (&Val::Empty, &Val::Empty) => Ok(true),
60 (&Val::Int(ref i), &Val::Int(ref ii)) => Ok(i == ii),
61 (&Val::Float(ref f), &Val::Float(ref ff)) => Ok(f == ff),
62 (&Val::Boolean(ref b), &Val::Boolean(ref bb)) => Ok(b == bb),
63 (&Val::Str(ref s), &Val::Str(ref ss)) => Ok(s == ss),
64 (&Val::List(ref ldef), &Val::List(ref rdef)) => {
65 if ldef.len() != rdef.len() {
66 Ok(false)
67 } else {
68 for (i, lv) in ldef.iter().enumerate() {
69 if !lv.equal(rdef[i].as_ref())? {
70 return Ok(false);
71 }
72 }
73 Ok(true)
74 }
75 }
76 (&Val::Tuple(ref ldef), &Val::Tuple(ref rdef)) => {
77 if ldef.len() != rdef.len() {
78 Ok(false)
79 } else {
80 for (i, lv) in ldef.iter().enumerate() {
81 let field_target = &rdef[i];
82 if lv.0 != field_target.0 {
83 return Ok(false);
85 } else {
86 if !lv.1.equal(field_target.1.as_ref())? {
88 return Ok(false);
89 }
90 }
91 }
92 Ok(true)
93 }
94 }
95 (&Val::Empty, _) => Ok(false),
97 (_, &Val::Empty) => Ok(false),
98 (me, tgt) => Err(error::BuildError::new(
99 format!("Expected {} but got ({})", me.type_name(), tgt),
100 error::ErrorType::TypeFail,
101 )),
102 }
103 }
104
105 pub fn get_fields(&self) -> Option<&Vec<(String, Rc<Val>)>> {
107 if let &Val::Tuple(ref fs) = self {
108 Some(fs)
109 } else {
110 None
111 }
112 }
113
114 pub fn is_int(&self) -> bool {
115 if let &Val::Int(_) = self {
116 return true;
117 }
118 return false;
119 }
120
121 pub fn is_empty(&self) -> bool {
122 if let &Val::Empty = self {
123 return true;
124 }
125 return false;
126 }
127
128 pub fn is_float(&self) -> bool {
129 if let &Val::Float(_) = self {
130 return true;
131 }
132 return false;
133 }
134
135 pub fn is_string(&self) -> bool {
136 if let &Val::Str(_) = self {
137 return true;
138 }
139 return false;
140 }
141
142 pub fn is_tuple(&self) -> bool {
143 if let &Val::Tuple(_) = self {
144 return true;
145 }
146 return false;
147 }
148
149 pub fn is_env(&self) -> bool {
150 if let &Val::Env(_) = self {
151 return true;
152 }
153 return false;
154 }
155
156 pub fn is_list(&self) -> bool {
157 if let &Val::List(_) = self {
158 return true;
159 }
160 return false;
161 }
162
163 pub fn is_bool(&self) -> bool {
164 if let &Val::Boolean(_) = self {
165 return true;
166 }
167 return false;
168 }
169
170 pub fn is_str(&self) -> bool {
171 if let &Val::Str(_) = self {
172 return true;
173 }
174 return false;
175 }
176}
177
178impl Display for Val {
179 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
180 match self {
181 &Val::Boolean(b) => write!(f, "{}", b),
182 &Val::Empty => write!(f, "NULL"),
183 &Val::Float(ref ff) => write!(f, "{}", ff),
184 &Val::Int(ref i) => write!(f, "{}", i),
185 &Val::Str(ref s) => write!(f, "\"{}\"", s.replace("\"", "\\\"")),
186 &Val::List(ref def) => {
187 write!(f, "[")?;
188 for v in def.iter() {
189 write!(f, "{}, ", v)?;
190 }
191 write!(f, "]")
192 }
193 &Val::Tuple(ref def) => {
194 write!(f, "{{\n")?;
195 for v in def.iter() {
196 write!(f, "\t{} = {},\n", v.0, v.1)?;
197 }
198 write!(f, "}}")
199 }
200 &Val::Env(ref def) => {
201 write!(f, "{{\n")?;
202 for v in def.iter() {
203 write!(f, "\t{}=\"{}\"\n", v.0, v.1)?;
204 }
205 write!(f, "}}")
206 }
207 }
208 }
209}
210
211impl From<Val> for String {
212 fn from(v: Val) -> String {
213 match v {
214 Val::Int(ref i) => format!("{}", i),
215 Val::Float(ref f) => format!("{}", f),
216 Val::Str(ref s) => s.to_string(),
217 Val::Boolean(ref b) => format!("{}", b),
218 Val::Empty => "NULL".to_string(),
219 val => format!("{}", val),
220 }
221 }
222}
223
224impl From<String> for Val {
225 fn from(s: String) -> Val {
226 Val::Str(s)
227 }
228}