1use std::convert::{From, TryFrom};
2use std::rc::Rc;
3
4use super::{Composite, Primitive, Val, Value};
5use crate::ast::{CastType, Position};
6
7use Composite::{List, Tuple};
8use Primitive::{Bool, Empty, Float, Int, Str};
9use Value::{C, F, M, P, S, T};
10
11pub struct Error {
12 val: Primitive,
13 cast_type: CastType,
14}
15
16impl Error {
17 pub fn message(&self) -> String {
18 format!("No cast from {} to {}", self.val, self.cast_type)
19 }
20}
21
22impl From<&Primitive> for String {
23 fn from(p: &Primitive) -> Self {
24 match p {
25 Primitive::Int(i) => format!("{}", i),
26 Primitive::Float(f) => format!("{}", f),
27 Primitive::Str(s) => format!("{}", s),
28 Primitive::Bool(b) => format!("{}", b),
29 Primitive::Empty => "NULL".to_owned(),
30 }
31 }
32}
33
34impl TryFrom<&Primitive> for i64 {
35 type Error = Error;
36
37 fn try_from(p: &Primitive) -> Result<Self, Self::Error> {
38 match p {
39 Primitive::Bool(_) | Primitive::Empty => Err(Error {
40 val: p.clone(),
41 cast_type: CastType::Int,
42 }),
43 Primitive::Str(s) => match s.parse::<i64>() {
44 Ok(i) => Ok(i),
45 Err(_) => Err(Error {
46 val: Primitive::Str(s.clone()),
47 cast_type: CastType::Int,
48 }),
49 },
50 Primitive::Float(f) => Ok(*f as i64),
51 Primitive::Int(i) => Ok(i.clone()),
52 }
53 }
54}
55
56impl TryFrom<&Primitive> for f64 {
57 type Error = Error;
58
59 fn try_from(p: &Primitive) -> Result<Self, Self::Error> {
60 match p {
61 Primitive::Bool(_) | Primitive::Empty => Err(Error {
62 val: p.clone(),
63 cast_type: CastType::Int,
64 }),
65 Primitive::Str(s) => match s.parse::<f64>() {
66 Ok(f) => Ok(f),
67 Err(_) => Err(Error {
68 val: Primitive::Str(s.clone()),
69 cast_type: CastType::Int,
70 }),
71 },
72 Primitive::Int(i) => Ok(*i as f64),
73 Primitive::Float(f) => Ok(f.clone()),
74 }
75 }
76}
77
78impl TryFrom<&Primitive> for bool {
79 type Error = Error;
80
81 fn try_from(p: &Primitive) -> Result<Self, Self::Error> {
82 match p {
83 Primitive::Empty | Primitive::Int(_) | Primitive::Float(_) => Err(Error {
84 val: p.clone(),
85 cast_type: CastType::Int,
86 }),
87 Primitive::Bool(b) => Ok(*b),
88 Primitive::Str(s) => match s.as_str() {
89 "true" => Ok(true),
90 "false" => Ok(false),
91 _ => Err(Error {
92 val: Primitive::Str(s.clone()),
93 cast_type: CastType::Int,
94 }),
95 },
96 }
97 }
98}
99
100impl From<Rc<Value>> for Val {
101 fn from(val: Rc<Value>) -> Val {
102 val.as_ref().into()
103 }
104}
105
106impl From<Value> for Val {
107 fn from(val: Value) -> Val {
108 (&val).into()
109 }
110}
111
112impl From<&Value> for Val {
113 fn from(val: &Value) -> Val {
114 match val {
115 P(Int(i)) => Val::Int(*i),
116 P(Float(f)) => Val::Float(*f),
117 P(Str(s)) => Val::Str(s.clone()),
118 P(Bool(b)) => Val::Boolean(*b),
119 C(Tuple(fs, _)) => {
120 let mut flds = Vec::new();
121 for &(ref k, ref v) in fs.iter() {
122 let v = v.clone();
123 flds.push((k.clone(), Rc::new(v.into())));
124 }
125 Val::Tuple(flds)
126 }
127 C(List(elems, _)) => {
128 let mut els = Vec::new();
129 for e in elems.iter() {
130 let e = e.clone();
131 els.push(Rc::new(e.into()));
132 }
133 Val::List(els)
134 }
135 S(_) | F(_) | M(_) | T(_) | P(Empty) => Val::Empty,
136 }
137 }
138}
139
140impl From<Rc<Val>> for Value {
141 fn from(val: Rc<Val>) -> Self {
142 val.as_ref().into()
143 }
144}
145
146impl From<Val> for Value {
147 fn from(val: Val) -> Self {
148 (&val).into()
149 }
150}
151
152impl From<&Val> for Value {
153 fn from(val: &Val) -> Self {
154 match val {
155 Val::Int(i) => P(Int(*i)),
156 Val::Float(f) => P(Float(*f)),
157 Val::Boolean(b) => P(Bool(*b)),
158 Val::Str(s) => P(Str(s.clone())),
159 Val::Empty => P(Empty),
160 Val::List(els) => {
161 let mut lst = Vec::new();
162 let mut positions = Vec::new();
163 for e in els.iter() {
164 let e = e.clone();
165 lst.push(Rc::new(e.into()));
166 positions.push(Position::new(0, 0, 0));
167 }
168 C(List(lst, positions))
171 }
172 Val::Tuple(flds) => {
173 let mut field_list = Vec::new();
174 let mut positions = Vec::new();
175 for &(ref key, ref val) in flds.iter() {
176 let val = val.clone();
177 field_list.push((key.clone(), Rc::new(val.into())));
178 positions.push((Position::new(0, 0, 0), Position::new(0, 0, 0)));
179 }
180 C(Tuple(field_list, positions))
181 }
182 Val::Env(flds) => {
183 let mut field_list = Vec::new();
184 let mut positions = Vec::new();
185 for &(ref key, ref val) in flds.iter() {
186 field_list.push((key.clone(), Rc::new(P(Str(val.clone())))));
187 positions.push((Position::new(0, 0, 0), Position::new(0, 0, 0)));
188 }
189 C(Tuple(field_list, positions))
190 }
191 }
192 }
193}
194
195impl From<&Composite> for String {
196 fn from(c: &Composite) -> Self {
197 let mut buf = String::new();
198 match c {
199 &List(ref elems, _) => {
200 buf.push_str("[");
201 for e in elems.iter() {
202 let val: String = e.as_ref().into();
203 buf.push_str(&val);
204 buf.push_str(",");
205 }
206 buf.push_str("]");
207 }
208 &Tuple(ref flds, _) => {
209 buf.push_str("{");
210 for &(ref k, ref v) in flds.iter() {
211 buf.push_str(&k);
212 buf.push_str(" = ");
213 let val: String = v.as_ref().into();
214 buf.push_str(&val);
215 buf.push_str(",");
216 }
217 buf.push_str("}");
218 }
219 }
220 buf
221 }
222}
223
224impl From<&Value> for String {
225 fn from(v: &Value) -> Self {
226 match v {
227 &S(ref s) => s.clone(),
228 &P(ref p) => p.into(),
229 &C(ref c) => c.into(),
230 &T(_) => "<Thunk>".to_owned(),
231 &F(_) => "<Func>".to_owned(),
232 &M(_) => "<Module>".to_owned(),
233 }
234 }
235}