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