Skip to main content

rustex_lib/
utils.rs

1use std::borrow::Cow;
2use std::fmt::{Debug, Formatter};
3use std::ops::{Add, AddAssign};
4use tex_engine::tex::numerics::{Dim32, Skip, StretchShrink};
5
6#[derive(Copy, Clone, Debug)]
7pub(crate) enum Flex {
8    Fixed(i32),
9    Fil(i32),
10    Fill(i32),
11    Filll(i32),
12}
13impl Default for Flex {
14    fn default() -> Self {
15        Flex::Fixed(0)
16    }
17}
18impl Flex {
19    fn is_zero(&self) -> bool {
20        match self {
21            Flex::Fixed(0) => true,
22            _ => false,
23        }
24    }
25}
26impl Add for Flex {
27    type Output = Self;
28    fn add(self, other: Self) -> Self {
29        match (self, other) {
30            (Flex::Fixed(a), Flex::Fixed(b)) => Flex::Fixed(a + b),
31            (Flex::Fil(a), Flex::Fil(b)) => Flex::Fil(a + b),
32            (Flex::Fill(a), Flex::Fill(b)) => Flex::Fill(a + b),
33            (Flex::Filll(a), Flex::Filll(b)) => Flex::Filll(a + b),
34            (Flex::Fixed(_), Flex::Fil(b)) => Flex::Fil(b),
35            (Flex::Fil(a), Flex::Fixed(_)) => Flex::Fil(a),
36            (Flex::Fixed(_) | Flex::Fil(_), Flex::Fill(b)) => Flex::Fill(b),
37            (Flex::Fill(a), Flex::Fixed(_) | Flex::Fil(_)) => Flex::Fill(a),
38            (_, Flex::Filll(b)) => Flex::Filll(b),
39            (Flex::Filll(a), _) => Flex::Filll(a),
40        }
41    }
42}
43impl From<StretchShrink<Dim32>> for Flex {
44    fn from(ss: StretchShrink<Dim32>) -> Self {
45        match ss {
46            StretchShrink::Dim(d) => Flex::Fixed(d.0),
47            StretchShrink::Fil(d) if d != 0 => Flex::Fil(d),
48            StretchShrink::Fill(d) if d != 0 => Flex::Fill(d),
49            StretchShrink::Filll(d) if d != 0 => Flex::Filll(d),
50            _ => Flex::Fixed(0),
51        }
52    }
53}
54#[derive(Copy, Clone)]
55pub(crate) struct Margin {
56    pub(crate) base: i32,
57    pub(crate) stretch: Flex,
58    pub(crate) shrink: Flex,
59}
60impl Debug for Margin {
61    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
62        write!(f, "<skip {}", self.base)?;
63        if !self.stretch.is_zero() {
64            write!(f, " plus {:?}", self.stretch)?;
65        }
66        if !self.shrink.is_zero() {
67            write!(f, " minus {:?}", self.shrink)?;
68        }
69        f.write_str(">")
70    }
71}
72impl Margin {
73    pub(crate) fn fil() -> Self {
74        Self {
75            base: 0,
76            stretch: Flex::Fil(1),
77            shrink: Flex::Fixed(0),
78        }
79    }
80    pub(crate) fn fill() -> Self {
81        Self {
82            base: 0,
83            stretch: Flex::Fill(1),
84            shrink: Flex::Fixed(0),
85        }
86    }
87    pub(crate) fn filll() -> Self {
88        Self {
89            base: 0,
90            stretch: Flex::Filll(1),
91            shrink: Flex::Fixed(0),
92        }
93    }
94    pub(crate) fn ss() -> Self {
95        Self {
96            base: 0,
97            stretch: Flex::Fil(1),
98            shrink: Flex::Fil(1),
99        }
100    }
101    pub(crate) fn is_zero(&self) -> bool {
102        self.base == 0 && self.stretch.is_zero() && self.shrink.is_zero()
103    }
104}
105impl Add for Margin {
106    type Output = Self;
107    fn add(self, other: Self) -> Self {
108        Self {
109            base: self.base + other.base,
110            stretch: self.stretch + other.stretch,
111            shrink: self.shrink + other.shrink,
112        }
113    }
114}
115impl From<Skip<Dim32>> for Margin {
116    fn from(skip: Skip<Dim32>) -> Self {
117        let base = skip.base.0;
118        let stretch = skip.stretch.map(|s| s.into()).unwrap_or_default();
119        let shrink = skip.shrink.map(|s| s.into()).unwrap_or_default();
120        Self {
121            base,
122            stretch,
123            shrink,
124        }
125    }
126}
127impl From<Dim32> for Margin {
128    fn from(dim: Dim32) -> Self {
129        Self {
130            base: dim.0,
131            stretch: Flex::Fixed(0),
132            shrink: Flex::Fixed(0),
133        }
134    }
135}
136impl AddAssign for Margin {
137    fn add_assign(&mut self, other: Self) {
138        self.base += other.base;
139        self.stretch = self.stretch + other.stretch;
140        self.shrink = self.shrink + other.shrink;
141    }
142}
143
144#[derive(Clone, Debug, PartialEq)]
145pub struct VecSet<K: PartialEq> {
146    pub inner: Vec<K>,
147}
148impl<K: PartialEq> Default for VecSet<K> {
149    #[inline]
150    fn default() -> Self {
151        Self { inner: Vec::new() }
152    }
153}
154impl<K: PartialEq> VecSet<K> {
155    #[inline]
156    pub fn contains(&self, key: &K) -> bool {
157        self.inner.contains(key)
158    }
159    #[inline]
160    pub fn insert(&mut self, key: K) {
161        if !self.inner.contains(&key) {
162            self.inner.push(key);
163        }
164    }
165}
166impl<K: PartialEq> IntoIterator for VecSet<K> {
167    type Item = K;
168    type IntoIter = std::vec::IntoIter<K>;
169    fn into_iter(self) -> Self::IntoIter {
170        self.inner.into_iter()
171    }
172}
173impl<K: PartialEq> FromIterator<K> for VecSet<K> {
174    fn from_iter<T: IntoIterator<Item = K>>(iter: T) -> Self {
175        let mut set = VecSet::default();
176        for item in iter {
177            set.insert(item);
178        }
179        set
180    }
181}
182
183#[derive(Clone)]
184pub struct VecMap<K, V> {
185    pub inner: Vec<(K, V)>,
186}
187impl<K: Debug, V: Debug> Debug for VecMap<K, V> {
188    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189        f.debug_map()
190            .entries(self.inner.iter().map(|(k, v)| (k, v)))
191            .finish()
192    }
193}
194impl<K, V> Default for VecMap<K, V> {
195    fn default() -> Self {
196        Self { inner: Vec::new() }
197    }
198}
199impl<K: PartialEq, V> VecMap<K, V> {
200    pub fn get<E: ?Sized>(&self, key: &E) -> Option<&V>
201    where
202        for<'a> &'a E: PartialEq<&'a K>,
203    {
204        self.inner.iter().find(|(k, _)| key == k).map(|(_, v)| v)
205    }
206    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
207        self.inner
208            .iter_mut()
209            .find(|(k, _)| k == key)
210            .map(|(_, v)| v)
211    }
212    pub fn insert(&mut self, key: K, value: V) {
213        match self.inner.iter_mut().find(|(k, _)| k == &key) {
214            Some((_, v)) => *v = value,
215            None => self.inner.push((key, value)),
216        };
217    }
218    pub fn get_or_insert_mut(&mut self, key: K, value: impl FnOnce() -> V) -> &mut V {
219        if let Some((i, (_, v))) = self.inner.iter().enumerate().find(|(_, (k, _))| k == &key) {
220            return &mut self.inner.get_mut(i).unwrap().1;
221        };
222        let value = value();
223        self.inner.push((key, value));
224        &mut self.inner.last_mut().unwrap().1
225    }
226    #[inline]
227    pub fn is_empty(&self) -> bool {
228        self.inner.is_empty()
229    }
230    pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
231        self.inner.iter().map(|(k, v)| (k, v))
232    }
233    pub fn contains_key<E: ?Sized>(&self, key: &E) -> bool
234    where
235        for<'a> &'a E: PartialEq<&'a K>,
236    {
237        self.inner.iter().any(|(k, _)| key == k)
238    }
239}
240impl<K, V> IntoIterator for VecMap<K, V> {
241    type Item = (K, V);
242    type IntoIter = std::vec::IntoIter<Self::Item>;
243    fn into_iter(self) -> Self::IntoIter {
244        self.inner.into_iter()
245    }
246}
247impl<'a, 'b> Into<VecMap<Cow<'a, str>, Cow<'b, str>>> for VecMap<String, String> {
248    fn into(self) -> VecMap<Cow<'a, str>, Cow<'b, str>> {
249        VecMap {
250            inner: self
251                .inner
252                .into_iter()
253                .map(|(k, v)| (Cow::Owned(k), Cow::Owned(v)))
254                .collect(),
255        }
256    }
257}