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}