cl_format/tildes/
args.rs

1use std::borrow::Cow;
2
3use super::*;
4
5/// The args for control string to use.
6#[derive(Debug, Clone)]
7pub struct Args<'a, 'arg> {
8    len: usize,
9    inner: Cow<'arg, [&'a dyn TildeAble]>,
10
11    /// need mutate borrow in immutate Args
12    ind: RefCell<usize>,
13}
14
15impl<'a, 'arg> Args<'a, 'arg> {
16    pub fn new(i: Vec<&'a dyn TildeAble>) -> Self {
17        Self {
18            len: i.len(),
19            inner: Cow::Owned(i),
20            ind: RefCell::new(0),
21        }
22    }
23
24    pub fn new_cow(i: &'arg [&'a dyn TildeAble]) -> Self {
25        Self {
26            len: i.len(),
27            inner: Cow::Borrowed(i),
28            ind: RefCell::new(0),
29        }
30    }
31
32    pub fn pop(&self) -> Option<&dyn TildeAble> {
33        let r = self.inner.get(*self.ind.borrow())?;
34        *self.ind.borrow_mut() += 1;
35        Some(*r)
36    }
37
38    pub fn back(&self) -> Option<&dyn TildeAble> {
39        let i = match *self.ind.borrow() {
40            0 => return None,
41            n @ _ => n - 1,
42        };
43
44        let r = self.inner.get(i)?;
45        *self.ind.borrow_mut() -= 1;
46        Some(*r)
47    }
48
49    pub fn left_count(&self) -> usize {
50        self.len - *self.ind.borrow()
51    }
52
53    pub fn reset(&self) {
54        *self.ind.borrow_mut() = 0;
55    }
56}
57
58impl<'a, const N: usize> From<[&'a dyn TildeAble; N]> for Args<'a, '_> {
59    fn from(value: [&'a dyn TildeAble; N]) -> Self {
60        Self::new(value.to_vec())
61    }
62}
63
64impl<'a, 'arg> From<&'arg [&'a dyn TildeAble]> for Args<'a, 'arg> {
65    fn from(value: &'arg [&'a dyn TildeAble]) -> Self {
66        Self::new_cow(value)
67    }
68}
69
70impl<'a> From<Vec<&'a dyn TildeAble>> for Args<'a, '_> {
71    fn from(value: Vec<&'a dyn TildeAble>) -> Self {
72        Self::new(value)
73    }
74}
75
76impl<'a, 'arg, T> From<&'arg T> for Args<'a, 'arg>
77where
78    T: Deref<Target = [&'a dyn TildeAble]>,
79{
80    fn from(value: &'arg T) -> Self {
81        Self::new_cow(value.deref())
82    }
83}
84
85impl<'a, 'arg> IntoIterator for Args<'a, 'arg> {
86    type Item = &'a dyn TildeAble;
87
88    type IntoIter = std::vec::IntoIter<&'a dyn TildeAble>;
89
90    fn into_iter(self) -> Self::IntoIter {
91        self.inner.into_owned().into_iter()
92    }
93}