1use std::cmp::Ordering;
6use std::collections::Bound;
7use std::fmt::{Display, Formatter, Result};
8use std::iter::Iterator;
9
10#[derive(Clone, Debug, PartialEq, PartialOrd)]
12pub enum E {
13 I(i32),
17 D(f64),
21 S(String),
25 T(Tuple),
29 Any,
35 None,
41}
42
43impl Eq for E {}
44
45impl Ord for E {
46 fn cmp(&self, other: &E) -> Ordering {
51 match (self, other) {
52 (&E::Any, &E::Any) => Ordering::Equal,
53 (&E::Any, _) => Ordering::Less,
54 (_, &E::Any) => Ordering::Greater,
55 (&E::None, &E::None) => Ordering::Equal,
56 (&E::None, _) => Ordering::Greater,
57 (_, &E::None) => Ordering::Less,
58 (&E::I(ref a), &E::I(ref b)) => a.cmp(b),
59 (&E::I(_), _) => Ordering::Less,
60 (_, &E::I(_)) => Ordering::Greater,
61 (&E::D(ref a), &E::D(ref b)) => {
62 if a < b {
63 Ordering::Less
64 } else if a > b {
65 Ordering::Greater
66 } else {
67 Ordering::Equal
68 }
69 }
70 (&E::D(_), _) => Ordering::Less,
71 (_, &E::D(_)) => Ordering::Greater,
72 (&E::S(ref a), &E::S(ref b)) => a.cmp(b),
73 (&E::S(_), _) => Ordering::Less,
74 (_, &E::S(_)) => Ordering::Greater,
75 (&E::T(ref a), &E::T(ref b)) => a.cmp(b),
76 }
77 }
78}
79
80impl Display for E {
81 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
82 write!(
83 f,
84 "{}",
85 match self {
86 E::I(ref i) => i.to_string(),
87 E::D(ref d) => d.to_string(),
88 E::S(ref s) => s.to_string(),
89 E::T(ref t) => t.to_string(),
90 E::Any => "_".to_string(),
91 E::None => "nil".to_string(),
92 }
93 )
94 }
95}
96
97impl E {
98 pub fn str<S: Into<String>>(s: S) -> E {
99 E::S(s.into())
100 }
101
102 pub fn is_defined(&self) -> bool {
104 match self {
105 E::I(_) => true,
106 E::D(_) => true,
107 E::S(_) => true,
108 E::Any => false,
109 E::None => false,
110 E::T(ref t) => t.is_defined(),
111 }
112 }
113
114 pub fn matches(&self, other: &E) -> bool {
118 let error = 0.001;
120 match (self, other) {
121 (&E::I(ref a), &E::I(ref b)) => a == b,
122 (&E::D(ref a), &E::D(ref b)) => (a - b).abs() < error,
123 (&E::S(ref a), &E::S(ref b)) => a == b,
124 (&E::T(ref a), &E::T(ref b)) => a.matches(b),
125 (&E::Any, &E::Any) => false,
126 (&E::Any, &E::None) => false,
127 (&E::Any, _) => true,
128 (&E::None, _) => false,
129 (_, &E::Any) => true,
130 _ => false,
131 }
132 }
133}
134
135#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
136pub struct Tuple(Vec<E>);
137
138impl Display for Tuple {
139 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
140 write!(
141 f,
142 "({})",
143 self.0
144 .iter()
145 .map(|x| x.to_string())
146 .collect::<Vec<String>>()
147 .join(",")
148 )
149 }
150}
151
152impl Tuple {
153 pub fn new(elements: &[E]) -> Tuple {
155 Tuple(elements.to_vec())
156 }
157
158 pub fn from_vec(v: Vec<E>) -> Tuple {
160 Tuple(v)
161 }
162
163 pub fn first(&self) -> &E {
165 &self.0[0]
166 }
167
168 pub fn rest(&self) -> Tuple {
170 Tuple::new(&self.0[1..])
171 }
172
173 pub fn is_empty(&self) -> bool {
175 self.0.is_empty()
176 }
177
178 pub fn is_defined(&self) -> bool {
181 self.0.iter().all(|ref x| x.is_defined())
182 }
183
184 pub fn matches(&self, other: &Tuple) -> bool {
186 (self.is_empty() == other.is_empty())
187 && self
188 .0
189 .iter()
190 .zip(other.0.iter())
191 .all(|(ref x, ref y): (&E, &E)| x.matches(y))
192 }
193
194 pub fn range(&self) -> (Bound<Tuple>, Bound<Tuple>) {
196 if self.is_defined() {
197 (Bound::Included(self.clone()), Bound::Excluded(self.clone()))
198 } else {
199 (
200 Bound::Excluded(self.clone()),
201 Bound::Excluded(self.terminator()),
202 )
203 }
204 }
205
206 fn terminator(&self) -> Tuple {
207 Tuple(
208 self.0
209 .iter()
210 .map(|x| match x {
211 &E::Any => E::None,
212 &E::T(ref t) => E::T(t.terminator()),
213 e => e.clone(),
214 })
215 .collect::<Vec<E>>(),
216 )
217 }
218}
219
220#[macro_export]
221macro_rules! tuple {
222 ($($x:expr),*) => (
223 $crate::tuple::Tuple::new(&[$($x), *])
224 );
225 ($($x:expr,)*) => (tuple![$($x),*])
226}