arithmetic_eval/values/
tuple.rs

1//! `Tuple` and tightly related types.
2
3use core::{fmt, iter::FromIterator, ops};
4
5use crate::{
6    alloc::{vec, Vec},
7    Value,
8};
9
10/// Tuple of zero or more values.
11///
12/// A tuple is similar to a [`Vec`] with [`Value`] elements and can be converted from / to it.
13/// It is possible to iterate over elements, index them, etc.
14///
15/// # Examples
16///
17/// ```
18/// # use arithmetic_eval::{Tuple, Value};
19/// let mut tuple = Tuple::<u32>::default();
20/// tuple.push(Value::Prim(3));
21/// tuple.push(Value::Prim(5));
22/// assert_eq!(tuple.len(), 2);
23/// assert_eq!(tuple[1], Value::Prim(5));
24/// assert!(tuple.iter().all(|val| !val.is_void()));
25///
26/// // `Tuple` implements `FromIterator` / `Extend`.
27/// let mut other_tuple: Tuple<u32> = (0..=2).map(Value::Prim).collect();
28/// other_tuple.extend(tuple);
29/// assert_eq!(other_tuple.len(), 5);
30/// ```
31#[derive(Debug, Clone, PartialEq)]
32pub struct Tuple<T> {
33    elements: Vec<Value<T>>,
34}
35
36impl<T> Default for Tuple<T> {
37    fn default() -> Self {
38        Self::void()
39    }
40}
41
42impl<T> From<Tuple<T>> for Value<T> {
43    fn from(tuple: Tuple<T>) -> Self {
44        Self::Tuple(tuple)
45    }
46}
47
48impl<T> From<Vec<Value<T>>> for Tuple<T> {
49    fn from(elements: Vec<Value<T>>) -> Self {
50        Self { elements }
51    }
52}
53
54impl<T> From<Tuple<T>> for Vec<Value<T>> {
55    fn from(tuple: Tuple<T>) -> Self {
56        tuple.elements
57    }
58}
59
60impl<T: fmt::Display> fmt::Display for Tuple<T> {
61    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
62        write!(formatter, "(")?;
63        for (i, element) in self.iter().enumerate() {
64            fmt::Display::fmt(element, formatter)?;
65            if i + 1 < self.len() {
66                formatter.write_str(", ")?;
67            } else if self.len() == 1 {
68                formatter.write_str(",")?; // terminal ',' to distinguish 1-element tuples
69            }
70        }
71        write!(formatter, ")")
72    }
73}
74
75impl<T> Tuple<T> {
76    /// Creates a new empty tuple (aka a void value).
77    pub const fn void() -> Self {
78        Self {
79            elements: Vec::new(),
80        }
81    }
82
83    /// Returns the number of elements in this tuple.
84    pub fn len(&self) -> usize {
85        self.elements.len()
86    }
87
88    /// Checks if this tuple is empty (has no elements).
89    pub fn is_empty(&self) -> bool {
90        self.elements.is_empty()
91    }
92
93    /// Iterates over the elements in this tuple.
94    pub fn iter(&self) -> impl Iterator<Item = &Value<T>> + '_ {
95        self.elements.iter()
96    }
97
98    /// Pushes a value to the end of this tuple.
99    pub fn push(&mut self, value: impl Into<Value<T>>) {
100        self.elements.push(value.into());
101    }
102}
103
104impl<T> ops::Index<usize> for Tuple<T> {
105    type Output = Value<T>;
106
107    fn index(&self, index: usize) -> &Self::Output {
108        &self.elements[index]
109    }
110}
111
112impl<T> IntoIterator for Tuple<T> {
113    type Item = Value<T>;
114    /// Iterator type should be considered an implementation detail.
115    type IntoIter = vec::IntoIter<Value<T>>;
116
117    fn into_iter(self) -> Self::IntoIter {
118        self.elements.into_iter()
119    }
120}
121
122impl<'r, T> IntoIterator for &'r Tuple<T> {
123    type Item = &'r Value<T>;
124    /// Iterator type should be considered an implementation detail.
125    type IntoIter = core::slice::Iter<'r, Value<T>>;
126
127    fn into_iter(self) -> Self::IntoIter {
128        self.elements.iter()
129    }
130}
131
132impl<T, V> FromIterator<V> for Tuple<T>
133where
134    V: Into<Value<T>>,
135{
136    fn from_iter<I: IntoIterator<Item = V>>(iter: I) -> Self {
137        Self {
138            elements: iter.into_iter().map(Into::into).collect(),
139        }
140    }
141}
142
143impl<T, V> Extend<V> for Tuple<T>
144where
145    V: Into<Value<T>>,
146{
147    fn extend<I: IntoIterator<Item = V>>(&mut self, iter: I) {
148        let new_elements = iter.into_iter().map(Into::into);
149        self.elements.extend(new_elements);
150    }
151}
152
153#[cfg(test)]
154mod tests {
155    use super::*;
156
157    #[test]
158    fn tuple_to_string() {
159        let mut tuple = Tuple::<f32>::default();
160        assert_eq!(tuple.to_string(), "()");
161
162        tuple.push(Value::Prim(3.0));
163        assert_eq!(tuple.to_string(), "(3,)");
164
165        tuple.push(Value::Prim(4.0));
166        assert_eq!(tuple.to_string(), "(3, 4)");
167    }
168}