nyar_collection/tuple/
mod.rs

1use im::{
2    vector::{Iter, IterMut},
3    Vector,
4};
5use nyar_error::NyarError;
6use shredder::{
7    marker::{GcDrop, GcSafe},
8    Scan, Scanner,
9};
10use std::{
11    collections::BTreeMap,
12    fmt::{Debug, Formatter},
13    hash::{Hash, Hasher},
14    iter::{Skip, StepBy, Take},
15};
16
17#[cfg(feature = "serde")]
18mod der;
19#[cfg(feature = "serde")]
20mod ser;
21
22mod iter;
23
24#[derive(Clone)]
25pub struct NyarTuple<T> {
26    raw: Vector<T>,
27    /// This is a compile time property
28    map: BTreeMap<Box<str>, usize>,
29}
30
31pub struct NyarTupleView<'i, T> {
32    raw: StepBy<Skip<Take<Iter<'i, T>>>>,
33    rev: bool,
34}
35
36pub struct NyarTupleEdit<'i, T> {
37    raw: StepBy<Skip<Take<IterMut<'i, T>>>>,
38    rev: bool,
39}
40
41impl<T: Clone> Default for NyarTuple<T> {
42    fn default() -> Self {
43        Self { raw: Vector::new(), map: BTreeMap::default() }
44    }
45}
46
47unsafe impl<T: GcSafe> GcSafe for NyarTuple<T> {}
48
49unsafe impl<T: GcDrop> GcDrop for NyarTuple<T> {}
50
51unsafe impl<T: Scan + Clone> Scan for NyarTuple<T> {
52    fn scan(&self, scanner: &mut Scanner<'_>) {
53        self.raw.iter().for_each(|v| scanner.scan(v))
54    }
55}
56
57impl<T: Clone + PartialEq> PartialEq<Self> for NyarTuple<T> {
58    /// If the two Tuple names are different, but the value is the same, it is deemed to be equal
59    fn eq(&self, other: &Self) -> bool {
60        self.raw.eq(&other.raw)
61    }
62}
63
64impl<T: Clone + Eq> Eq for NyarTuple<T> {}
65
66impl<T: Clone + Hash> Hash for NyarTuple<T> {
67    /// If the two Tuple names are different, but the value is the same, it will be deduplicated
68    fn hash<H: Hasher>(&self, state: &mut H) {
69        self.raw.iter().for_each(|v| v.hash(state));
70    }
71}
72
73impl<T: Clone> Debug for NyarTuple<T>
74where
75    T: Debug,
76{
77    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
78        f.debug_list().entries(self.raw.iter()).finish()
79    }
80}
81
82impl<T, U> FromIterator<U> for NyarTuple<T>
83where
84    U: Into<T>,
85    T: Clone,
86{
87    fn from_iter<I>(items: I) -> Self
88    where
89        I: IntoIterator<Item = U>,
90    {
91        let mut empty = NyarTuple::default();
92        for item in items.into_iter() {
93            empty.raw.push_back(item.into());
94        }
95        empty
96    }
97}
98
99impl<T: Clone> NyarTuple<T> {
100    pub fn cast_offset(&self, ordinal: isize) -> Option<usize> {
101        let offset = if ordinal == 0 {
102            return None;
103        }
104        else if ordinal > 0 {
105            ordinal - 1
106        }
107        else {
108            let max = self.raw.len() as isize;
109            if 0 > max + ordinal {
110                return None;
111            }
112            max + ordinal
113        };
114        Some(offset as usize)
115    }
116    pub fn get_offset(&self, offset: usize) -> Option<&T> {
117        self.raw.get(offset)
118    }
119    pub fn get_ordinal(&self, ordinal: isize) -> Option<&T> {
120        self.get_offset(self.cast_offset(ordinal)?)
121    }
122    pub fn get_named(&self, name: &str) -> Option<&T> {
123        let index = self.map.get(name)?;
124        self.raw.get(*index)
125    }
126    /// Obtain an immutable view, the start and end are both closed ranges
127    ///
128    /// # Arguments
129    ///
130    /// * `head`: The ordinal number of the starting element
131    /// * `tail`: The ordinal number of the ending element
132    /// * `step`: Step between each element
133    ///
134    /// # Examples
135    ///
136    /// ```vk
137    /// 0..=9[1: 1] = [0]
138    /// 0..=9[1:-1] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
139    /// 0..=9[1: 2] = [0, 1]
140    /// 0..=9[1:-2] = [0, 1, 2, 3, 4, 5, 6, 7, 8]
141    /// 0..=9[1: 3] = [0, 1, 2]
142    /// 0..=9[1:-3] = [0, 1, 2, 3, 4, 5, 6, 7]
143    /// 0..=9[:: 1] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
144    /// 0..=9[::-1] = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
145    /// 0..=9[:: 2] = [0, 2, 4, 6, 8]
146    /// 0..=9[::-2] = [8, 6, 4, 2, 0]
147    /// 0..=9[:: 3] = [0, 3, 6, 9]
148    /// 0..=9[::-3] = [9, 6, 3, 0]
149    /// ```
150    pub fn get_range(&self, head: isize, tail: isize, step: isize) -> NyarTupleView<T> {
151        let start = self.cast_offset(head).unwrap_or(self.raw.len() + 1);
152        let end = self.cast_offset(tail).unwrap_or(0) + 1;
153        // println!("{}: {} -> {}", self.raw.len(), start, end);
154        if step > 0 {
155            NyarTupleView { raw: self.raw.iter().take(end).skip(start).step_by(step.unsigned_abs()), rev: false }
156        }
157        else {
158            NyarTupleView { raw: self.raw.iter().take(end).skip(start).step_by(step.unsigned_abs()), rev: true }
159        }
160    }
161    /// Insert a named element starting from the back
162    ///
163    /// # Arguments
164    ///
165    /// * `name`:
166    /// * `item`:
167    ///
168    /// returns: Result<(), String>
169    ///
170    /// # Examples
171    ///
172    /// ```vk
173    /// ```
174    pub fn append_named<I: Into<T>>(&mut self, name: &str, item: I) -> Result<(), NyarError> {
175        if self.map.contains_key(name) {
176            return Err(NyarError::runtime_error(format!(
177                "Tuple key `{name}` already exists and cannot be created or written again"
178            )));
179        }
180        self.raw.push_back(item.into());
181        self.map.insert(Box::from(name), self.raw.len());
182        Ok(())
183    }
184    /// Append one element
185    ///
186    /// # Arguments
187    ///
188    /// * `item`:
189    ///
190    /// returns: ()
191    ///
192    /// # Examples
193    ///
194    /// ```
195    /// ```
196    pub fn append_one<I: Into<T>>(&mut self, item: I) {
197        self.raw.push_back(item.into())
198    }
199    /// Append many elements
200    ///
201    /// # Arguments
202    ///
203    /// * `items`:
204    ///
205    /// returns: ()
206    ///
207    /// # Examples
208    ///
209    /// ```
210    /// ```
211    pub fn append_many<I: Iterator<Item = T>>(&mut self, items: I) {
212        for item in items {
213            self.append_one(item)
214        }
215    }
216    /// Insert a named element starting from the front
217    ///
218    /// # Arguments
219    ///
220    /// * `name`:
221    /// * `item`:
222    ///
223    /// # Examples
224    ///
225    /// ```vk
226    /// ```
227    pub fn prepend_named<I: Into<T>>(&mut self, name: &str, item: I) -> Result<(), NyarError> {
228        if self.map.contains_key(name) {
229            return Err(NyarError::runtime_error(format!(
230                "Tuple key `{name}` already exists and cannot be created or written again"
231            )));
232        }
233        self.raw.push_back(item.into());
234        for value in self.map.values_mut() {
235            *value += 1;
236        }
237        self.map.insert(Box::from(name), 0);
238        Ok(())
239    }
240    /// Prepend one
241    ///
242    /// # Arguments
243    ///
244    /// * `item`:
245    ///
246    /// returns: ()
247    ///
248    /// # Examples
249    ///
250    /// ```
251    /// ```
252    pub fn prepend_one<I: Into<T>>(&mut self, item: I) {
253        self.raw.push_front(item.into())
254    }
255    /// Prepend many
256    ///
257    /// # Arguments
258    ///
259    /// * `items`:
260    ///
261    /// returns: ()
262    ///
263    /// # Examples
264    ///
265    /// ```
266    /// ```
267    pub fn prepend_many<I: Iterator<Item = T>>(&mut self, items: I) {
268        for item in items {
269            self.prepend_one(item)
270        }
271    }
272}