1#[cfg(test)]
2mod tests;
3
4use std::path::{Path, PathBuf};
5
6#[macro_export]
10macro_rules! count {
11 () => (0_usize);
12 ($x:tt, $($xs:tt),*) => (1_usize + $crate::count!($($xs)*));
13 ($x:tt, $($xs:tt)*) => (1_usize + $crate::count!($($xs)*));
14 ($x:tt $($xs:tt)*) => (1_usize + $crate::count!($($xs)*));
15}
16
17#[macro_export]
27macro_rules! inplace_vec {
28 ($($x:expr),* $(,)?) => {{
29 use std::mem::{self, MaybeUninit};
30 use std::borrow::Cow;
31
32 const SIZE: usize = $crate::count!($($x)*);
33
34 #[allow(unused_assignments)]
35 #[expect(clippy::transmute_undefined_repr)]
36 #[expect(clippy::macro_metavars_in_unsafe)]
37 unsafe {
39 let mut v: Vec<MaybeUninit<Cow<_>>> = Vec::with_capacity(SIZE);
40 v.set_len(SIZE);
41
42 let mut idx = 0;
43 $(
44 v[idx] = MaybeUninit::new($x.into());
45 idx += 1;
46 )*
47
48 mem::transmute::<Vec<MaybeUninit<Cow<_>>>, Vec<Cow<_>>>(v)
49 }
50 }};
51}
52
53#[macro_export]
54macro_rules! ref_smallvec {
55 ($t:ty, $size:expr, [$($x:expr),* $(,)?]$(,)?) => {{
56 let mut sv = SmallVec::<[&$t; $size]>::new_const();
57
58 sv.extend(
59 [
60 $(
61 AsRef::<$t>::as_ref($x),
62 )*
63 ]
64 );
65
66 sv
67 }};
68}
69
70#[macro_export]
71macro_rules! into_vec {
72 ($($x:expr),* $(,)?) => {
73 vec![
74 $(
75 $x.into(),
76 )*
77 ]
78 };
79}
80
81#[macro_export]
82macro_rules! into_array {
83 ($($x:expr),* $(,)?) => {
84 [
85 $(
86 $x.into(),
87 )*
88 ]
89 };
90}
91
92#[macro_export]
93macro_rules! into_smallvec {
94 ($($x:expr),* $(,)?) => {
95 smallvec::smallvec![
96 $(
97 $x.into(),
98 )*
99 ]
100 };
101}
102
103#[macro_export]
106macro_rules! create_dir {
107 ($loc:expr) => {
108 match std::fs::create_dir_all(&$loc) {
109 Ok(()) => Ok(()),
110 Err(e) => match e.kind() {
111 std::io::ErrorKind::AlreadyExists => Ok(()),
112 _ => {
113 error!("Error while creating directory {:?}: {}", &$loc, e);
114 Err(e)
115 },
116 },
117 }
118 };
119}
120
121#[inline]
122pub(crate) fn printable_base10_digits(x: usize) -> u32 {
123 (((x as f64).log10() + 1.0).floor() as u32).max(1)
124}
125
126#[inline]
129pub fn read_in_dir(path: &Path) -> anyhow::Result<impl Iterator<Item = PathBuf>> {
130 let dir = std::fs::read_dir(path)?;
131 Ok(dir.into_iter().filter_map(Result::ok).filter_map(|d| {
132 d.file_type().map_or(None, |file_type| (!file_type.is_dir()).then(|| d.path()))
133 }))
134}