1use std::collections::{HashMap, HashSet};
2use std::path::PathBuf;
3use std::process::Command;
4
5pub mod compression;
6pub mod io;
7#[cfg(feature = "mem")]
8pub mod mem;
9pub mod progress_bar;
10pub mod serde_helpers;
11pub mod time;
12
13pub mod tl;
14
15pub mod futures {
16 pub use self::box_future_or_noop::BoxFutureOrNoop;
17 pub use self::join_task::JoinTask;
18 pub use self::shared::{Shared, WeakShared};
19
20 mod box_future_or_noop;
21 mod join_task;
22 mod shared;
23}
24
25pub mod sync {
26 pub use self::once_take::*;
27 pub use self::priority_semaphore::{AcquireError, PrioritySemaphore, TryAcquireError};
28 pub use self::rayon::{rayon_run, rayon_run_fifo};
29 pub use self::task::{CancellationFlag, DebounceCancellationFlag, yield_on_complex};
30
31 mod once_take;
32 mod priority_semaphore;
33 mod rayon;
34 mod task;
35}
36
37#[cfg(any(test, feature = "test"))]
38pub mod test {
39 pub use self::logger::init_logger;
40
41 mod logger;
42}
43
44pub mod metrics {
45 pub use self::gauge_guard::GaugeGuard;
46 pub use self::histogram_guard::{HistogramGuard, HistogramGuardWithLabels};
47 pub use self::metrics_loop::spawn_metrics_loop;
48
49 mod gauge_guard;
50 mod histogram_guard;
51 mod metrics_loop;
52}
53
54mod util {
55 pub(crate) mod linked_list;
56 pub(crate) mod wake_list;
57}
58
59#[cfg(feature = "cli")]
60pub mod cli;
61
62pub use dashmap::mapref::entry::Entry as DashMapEntry;
63
64pub type FastDashMap<K, V> = dashmap::DashMap<K, V, ahash::RandomState>;
65pub type FastDashSet<K> = dashmap::DashSet<K, ahash::RandomState>;
66pub type FastHashMap<K, V> = HashMap<K, V, ahash::RandomState>;
67pub type FastHashSet<K> = HashSet<K, ahash::RandomState>;
68pub type FastHasherState = ahash::RandomState;
69
70#[macro_export]
91macro_rules! realloc_box_enum {
92 ($value:expr, {
93 $target_variant:pat => Box::new($extracted:ident) => $target:expr,
94 $other_variant:pat => $other:expr,
95 }) => {{
96 let value: ::std::boxed::Box<_> = $value;
97 match ::core::convert::AsRef::as_ref(&value) {
98 #[allow(unused_variables)]
99 $target_variant => {
100 let $extracted = unsafe {
101 $crate::__internal::realloc_box(value, |value| match value {
102 $target_variant => $extracted,
103 _ => unreachable!(),
104 })
105 };
106 $target
107 }
108 $other_variant => $other,
109 }
110 }};
111}
112
113#[doc(hidden)]
114pub mod __internal {
115 pub unsafe fn realloc_box<T, F, R>(value: Box<T>, f: F) -> Box<R>
120 where
121 F: FnOnce(T) -> R,
122 {
123 unsafe {
124 assert!(std::mem::align_of::<T>() == std::mem::align_of::<R>());
125
126 let ptr = Box::into_raw(value);
127 let value = std::ptr::read(ptr);
128
129 let ptr = std::alloc::realloc(
130 ptr.cast::<u8>(),
131 std::alloc::Layout::new::<T>(),
132 std::mem::size_of::<R>(),
133 )
134 .cast::<R>();
135
136 if ptr.is_null() {
137 std::alloc::handle_alloc_error(std::alloc::Layout::new::<R>());
138 }
139
140 std::ptr::write(ptr, f(value));
142
143 Box::from_raw(ptr)
144 }
145 }
146}
147
148pub fn project_root() -> Result<PathBuf, std::io::Error> {
149 let project_root = Command::new("git")
150 .arg("rev-parse")
151 .arg("--show-toplevel")
152 .output()?
153 .stdout;
154 let project_root = PathBuf::from(
156 String::from_utf8(project_root)
157 .map_err(|e| std::io::Error::other(format!("invalid project root: {e}")))?
158 .trim(),
159 );
160 Ok(project_root)
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166
167 #[test]
168 #[allow(dead_code)]
169 fn realloc_enum() {
170 enum Value {
171 One(BigValue1),
172 Two(BigValue2),
173 }
174
175 #[derive(Clone)]
176 struct BigValue1([u32; 10]);
177
178 #[derive(Clone)]
179 struct BigValue2([u32; 7]);
180
181 fn convert_to_one(value: Box<Value>) -> Option<Box<BigValue1>> {
182 realloc_box_enum!(value, {
183 Value::One(value) => Box::new(value) => Some(value),
184 _ => None,
185 })
186 }
187
188 let value = BigValue1([123; 10]);
189 let one = convert_to_one(Box::new(Value::One(value.clone())));
190 assert_eq!(one.unwrap().0, value.0);
191 }
192}