1pub mod fat;
4
5#[macro_use]
6mod macros;
7mod bitset;
8mod deferred;
9mod duration;
10mod hash;
11mod listset;
12mod pico;
13mod protected;
14mod round;
15mod scalar;
16#[path = "version.rs"]
17mod version_;
18
19pub use self::bitset::{BitSet, SmallBitSet};
20pub use self::deferred::Deferred;
21pub use self::duration::format_duration;
22pub use self::hash::{HashLock, LazyHash, ManuallyHash, hash128};
23pub use self::listset::ListSet;
24pub use self::pico::{PicoStr, ResolvedPicoStr};
25pub use self::protected::Protected;
26pub use self::round::{round_int_with_precision, round_with_precision};
27pub use self::scalar::Scalar;
28pub use self::version_::{TypstVersion, display_commit, version};
29
30#[doc(hidden)]
31pub use once_cell;
32
33use std::fmt::{Debug, Display, Formatter};
34use std::hash::Hash;
35use std::iter::{Chain, Flatten, Rev};
36use std::num::{NonZeroU32, NonZeroUsize};
37use std::ops::{Add, Deref, DerefMut, Div, Mul, Neg, Sub};
38
39use smallvec::SmallVec;
40use unicode_math_class::MathClass;
41
42pub fn debug<F>(f: F) -> impl Debug
44where
45 F: Fn(&mut Formatter) -> std::fmt::Result,
46{
47 struct Wrapper<F>(F);
48
49 impl<F> Debug for Wrapper<F>
50 where
51 F: Fn(&mut Formatter) -> std::fmt::Result,
52 {
53 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54 self.0(f)
55 }
56 }
57
58 Wrapper(f)
59}
60
61pub fn display<F>(f: F) -> impl Display
63where
64 F: Fn(&mut Formatter) -> std::fmt::Result,
65{
66 struct Wrapper<F>(F);
67
68 impl<F> Display for Wrapper<F>
69 where
70 F: Fn(&mut Formatter) -> std::fmt::Result,
71 {
72 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
73 self.0(f)
74 }
75 }
76
77 Wrapper(f)
78}
79
80pub trait NonZeroExt {
82 const ONE: Self;
84}
85
86impl NonZeroExt for NonZeroUsize {
87 const ONE: Self = Self::new(1).unwrap();
88}
89
90impl NonZeroExt for NonZeroU32 {
91 const ONE: Self = Self::new(1).unwrap();
92}
93
94pub trait OptionExt<T> {
96 fn map_or_default<U: Default, F>(self, f: F) -> U
99 where
100 F: FnOnce(T) -> U;
101}
102
103impl<T> OptionExt<T> for Option<T> {
104 fn map_or_default<U: Default, F>(self, f: F) -> U
105 where
106 F: FnOnce(T) -> U,
107 {
108 match self {
109 Some(x) => f(x),
110 None => U::default(),
111 }
112 }
113}
114
115pub trait SliceExt<T> {
117 fn trim_start_matches<F>(&self, f: F) -> &[T]
120 where
121 F: FnMut(&T) -> bool;
122
123 fn trim_end_matches<F>(&self, f: F) -> &[T]
126 where
127 F: FnMut(&T) -> bool;
128
129 fn group_by_key<K, F>(&self, f: F) -> GroupByKey<'_, T, F>
132 where
133 F: FnMut(&T) -> K,
134 K: PartialEq;
135
136 fn split_prefix_suffix<F>(&self, f: F) -> (usize, usize)
147 where
148 F: FnMut(&T) -> bool;
149}
150
151impl<T> SliceExt<T> for [T] {
152 fn trim_start_matches<F>(&self, mut f: F) -> &[T]
153 where
154 F: FnMut(&T) -> bool,
155 {
156 let len = self.len();
157 let mut i = 0;
158 while i < len && f(&self[i]) {
159 i += 1;
160 }
161 &self[i..]
162 }
163
164 fn trim_end_matches<F>(&self, mut f: F) -> &[T]
165 where
166 F: FnMut(&T) -> bool,
167 {
168 let mut i = self.len();
169 while i > 0 && f(&self[i - 1]) {
170 i -= 1;
171 }
172 &self[..i]
173 }
174
175 fn group_by_key<K, F>(&self, f: F) -> GroupByKey<'_, T, F> {
176 GroupByKey { slice: self, f }
177 }
178
179 fn split_prefix_suffix<F>(&self, mut f: F) -> (usize, usize)
180 where
181 F: FnMut(&T) -> bool,
182 {
183 let start = self.iter().position(|v| !f(v)).unwrap_or(self.len());
184 let end = self
185 .iter()
186 .skip(start)
187 .rposition(|v| !f(v))
188 .map_or(start, |i| start + i + 1);
189 (start, end)
190 }
191}
192
193pub trait Rdedup {
195 type Item;
196
197 fn rdedup_by_key<K, F>(&mut self, key: F)
200 where
201 F: Fn(&mut Self::Item) -> K,
202 K: PartialEq<K>;
203}
204
205impl<T: Copy, const N: usize> Rdedup for SmallVec<[T; N]> {
206 type Item = T;
207
208 fn rdedup_by_key<K, F>(&mut self, mut key: F)
209 where
210 T: Copy,
211 K: PartialEq<K>,
212 F: FnMut(&mut T) -> K,
213 {
214 let mut k = 0;
215 for i in 1..self.len() {
216 if key(&mut self[i]) != key(&mut self[k]) {
217 k += 1;
218 }
219 if k < i {
220 self[k] = self[i];
221 }
222 }
223 self.truncate(k + 1);
224 }
225}
226
227pub struct GroupByKey<'a, T, F> {
229 slice: &'a [T],
230 f: F,
231}
232
233impl<'a, T, K, F> Iterator for GroupByKey<'a, T, F>
234where
235 F: FnMut(&T) -> K,
236 K: PartialEq,
237{
238 type Item = (K, &'a [T]);
239
240 fn next(&mut self) -> Option<Self::Item> {
241 let mut iter = self.slice.iter();
242 let key = (self.f)(iter.next()?);
243 let count = 1 + iter.take_while(|t| (self.f)(t) == key).count();
244 let (head, tail) = self.slice.split_at(count);
245 self.slice = tail;
246 Some((key, head))
247 }
248}
249
250pub trait MaybeReverseIter {
252 type RevIfIter;
253
254 fn rev_if(self, condition: bool) -> Self::RevIfIter
256 where
257 Self: Sized;
258}
259
260impl<I: Iterator + DoubleEndedIterator> MaybeReverseIter for I {
261 type RevIfIter =
262 Chain<Flatten<std::option::IntoIter<I>>, Flatten<std::option::IntoIter<Rev<I>>>>;
263
264 fn rev_if(self, condition: bool) -> Self::RevIfIter
265 where
266 Self: Sized,
267 {
268 let (maybe_self_iter, maybe_rev_iter) =
269 if condition { (None, Some(self.rev())) } else { (Some(self), None) };
270
271 maybe_self_iter
272 .into_iter()
273 .flatten()
274 .chain(maybe_rev_iter.into_iter().flatten())
275 }
276}
277
278pub fn option_eq<L, R>(left: Option<L>, other: R) -> bool
280where
281 L: PartialEq<R>,
282{
283 left.is_some_and(|v| v == other)
284}
285
286#[derive(Debug)]
288pub struct Static<T: 'static>(pub &'static T);
289
290impl<T> Deref for Static<T> {
291 type Target = T;
292
293 fn deref(&self) -> &Self::Target {
294 self.0
295 }
296}
297
298impl<T> Copy for Static<T> {}
299
300impl<T> Clone for Static<T> {
301 fn clone(&self) -> Self {
302 *self
303 }
304}
305
306impl<T> Eq for Static<T> {}
307
308impl<T> PartialEq for Static<T> {
309 fn eq(&self, other: &Self) -> bool {
310 std::ptr::eq(self.0, other.0)
311 }
312}
313
314impl<T> Hash for Static<T> {
315 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
316 state.write_usize(self.0 as *const _ as _);
317 }
318}
319
320pub trait Get<Index> {
322 type Component;
324
325 fn get_ref(&self, index: Index) -> &Self::Component;
327
328 fn get_mut(&mut self, index: Index) -> &mut Self::Component;
330
331 fn get(self, index: Index) -> Self::Component
333 where
334 Self: Sized,
335 Self::Component: Copy,
336 {
337 *self.get_ref(index)
338 }
339
340 fn set(&mut self, index: Index, component: Self::Component) {
342 *self.get_mut(index) = component;
343 }
344
345 fn with(mut self, index: Index, component: Self::Component) -> Self
347 where
348 Self: Sized,
349 {
350 self.set(index, component);
351 self
352 }
353}
354
355pub trait Numeric:
357 Sized
358 + Debug
359 + Copy
360 + PartialEq
361 + Neg<Output = Self>
362 + Add<Output = Self>
363 + Sub<Output = Self>
364 + Mul<f64, Output = Self>
365 + Div<f64, Output = Self>
366{
367 fn zero() -> Self;
369
370 fn is_zero(self) -> bool {
372 self == Self::zero()
373 }
374
375 fn is_finite(self) -> bool;
377}
378
379pub trait NumericLength: Numeric {}
381
382pub fn default_math_class(c: char) -> Option<MathClass> {
386 match c {
387 ':' => Some(MathClass::Relation),
390
391 '⋯' | '⋱' | '⋰' | '⋮' => Some(MathClass::Normal),
394
395 '.' | '/' => Some(MathClass::Normal),
398
399 '\u{22A5}' => Some(MathClass::Normal),
402
403 '⅋' => Some(MathClass::Binary),
407
408 '⎰' | '⟅' => Some(MathClass::Opening),
412 '⎱' | '⟆' => Some(MathClass::Closing),
413
414 '⟇' => Some(MathClass::Binary),
417
418 '،' => Some(MathClass::Punctuation),
421
422 c => unicode_math_class::class(c),
423 }
424}
425
426pub fn defer<T, F: FnOnce(&mut T)>(
428 thing: &mut T,
429 deferred: F,
430) -> impl DerefMut<Target = T> {
431 pub struct DeferHandle<'a, T, F: FnOnce(&mut T)> {
432 thing: &'a mut T,
433 deferred: Option<F>,
434 }
435
436 impl<'a, T, F: FnOnce(&mut T)> Drop for DeferHandle<'a, T, F> {
437 fn drop(&mut self) {
438 std::mem::take(&mut self.deferred).expect("deferred function")(self.thing);
439 }
440 }
441
442 impl<T, F: FnOnce(&mut T)> std::ops::Deref for DeferHandle<'_, T, F> {
443 type Target = T;
444
445 fn deref(&self) -> &Self::Target {
446 self.thing
447 }
448 }
449
450 impl<T, F: FnOnce(&mut T)> std::ops::DerefMut for DeferHandle<'_, T, F> {
451 fn deref_mut(&mut self) -> &mut Self::Target {
452 self.thing
453 }
454 }
455
456 DeferHandle { thing, deferred: Some(deferred) }
457}
458
459#[derive(Debug, Copy, Clone, Eq, PartialEq)]
468pub struct DefSite {
469 pub path: &'static str,
473 pub key: &'static str,
476}
477
478#[macro_export]
481macro_rules! display_possible_values {
482 ($ty:ty) => {
483 impl std::fmt::Display for $ty {
484 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
485 self.to_possible_value()
486 .expect("no values are skipped")
487 .get_name()
488 .fmt(f)
489 }
490 }
491 };
492}
493
494#[cfg(test)]
495mod tests {
496 use super::*;
497
498 #[test]
499 fn test_rdedup() {
500 #[track_caller]
501 fn test(given: &[(char, i32)], expected: &[(char, i32)]) {
502 let mut vec: SmallVec<[(char, i32); 2]> = given.into();
503 vec.rdedup_by_key(|&mut (c, _)| c);
504 assert_eq!(vec.as_slice(), expected);
505 }
506
507 test(&[], &[]);
508 test(&[('a', 1), ('a', 2), ('a', 3), ('b', 2)], &[('a', 3), ('b', 2)]);
509 test(&[('b', 2), ('c', 3), ('c', 4)], &[('b', 2), ('c', 4)]);
510 test(
511 &[('a', 1), ('b', 1), ('c', 1), ('c', 2), ('d', 1)],
512 &[('a', 1), ('b', 1), ('c', 2), ('d', 1)],
513 );
514 }
515}