rustupolis/
tuple.rs

1//! Module Tuple
2//!
3//! Tuple is the basis for everything that can be put into the tuple space.
4
5use std::cmp::Ordering;
6use std::collections::Bound;
7use std::fmt::{Display, Formatter, Result};
8use std::iter::Iterator;
9
10/// E represents a tuple element.
11#[derive(Clone, Debug, PartialEq, PartialOrd)]
12pub enum E {
13    /// Integer data type.
14    ///
15    /// Implemented as 32-bit integer (i32).
16    I(i32),
17    /// Floating point data type.
18    ///
19    /// Implemented as double precision (f64).
20    D(f64),
21    /// String data type.
22    ///
23    /// Implemented as String.
24    S(String),
25    /// Tuple data type.
26    ///
27    /// Implemented as vector of tuple types (Vec<E>).
28    T(Tuple),
29    /// Any data type.
30    ///
31    /// In context of this tuple, Any stands for the wild card that is used for pattern matching
32    /// when querying the tuple space for certain tuples, and marks the beginning of a matching
33    /// range when searching for matching tuples.
34    Any,
35    /// None data type.
36    ///
37    /// In context of this tuple, None represents "no match" when searching, and marks the end of a
38    /// matching range when searching for matching tuples. All defined values will fall between
39    /// Any..None.
40    None,
41}
42
43impl Eq for E {}
44
45impl Ord for E {
46    /// Tuple elements have a well-defined ordering. Ordering among values of the same variant is
47    /// consistent with its contained type. Ordering among variants of different types is
48    /// mathematically and logically arbitrary but strongly consistent for the purpose of storage
49    /// and retrieval in data structures.
50    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    /// Returns true if one or more elements are the wildcard E::Any, recursively.
103    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    /// Returns true if the other tuple matches this one. Tuples match when elements in each
115    /// respective position are equal, or one or both of them in a given position is the wildcard
116    /// E::Any.
117    pub fn matches(&self, other: &E) -> bool {
118        // TODO: Don't use hard-coded error.
119        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    /// Creates a new tuple from a given array of elements.
154    pub fn new(elements: &[E]) -> Tuple {
155        Tuple(elements.to_vec())
156    }
157
158    /// Creates a new tuple from a given vector of elements.
159    pub fn from_vec(v: Vec<E>) -> Tuple {
160        Tuple(v)
161    }
162
163    /// Returns a reference to the first element of the tuple.
164    pub fn first(&self) -> &E {
165        &self.0[0]
166    }
167
168    /// Returns a tuple of all but the first element of the original tuple.
169    pub fn rest(&self) -> Tuple {
170        Tuple::new(&self.0[1..])
171    }
172
173    /// Returns true if the tuple is empty, false otherwise.
174    pub fn is_empty(&self) -> bool {
175        self.0.is_empty()
176    }
177
178    /// Returns true if all elements are defined, i.e: none of them are wildcards.
179    /// Returns false if the tuple contains any wildcards.
180    pub fn is_defined(&self) -> bool {
181        self.0.iter().all(|ref x| x.is_defined())
182    }
183
184    /// Returns true if this tuple matches the other.
185    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    /// Returns a range over this tuple.
195    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}