diff options
Diffstat (limited to 'crates/stdx/src/lib.rs')
-rw-r--r-- | crates/stdx/src/lib.rs | 70 |
1 files changed, 60 insertions, 10 deletions
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 374ed5910..1ff2559bb 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs | |||
@@ -1,9 +1,11 @@ | |||
1 | //! Missing batteries for standard libraries. | 1 | //! Missing batteries for standard libraries. |
2 | use std::time::Instant; | 2 | use std::{cmp::Ordering, ops, process, time::Instant}; |
3 | 3 | ||
4 | mod macros; | 4 | mod macros; |
5 | pub mod panic_context; | 5 | pub mod panic_context; |
6 | 6 | ||
7 | pub use crate::macros::{on_assert_failure, set_assert_hook}; | ||
8 | |||
7 | #[inline(always)] | 9 | #[inline(always)] |
8 | pub fn is_ci() -> bool { | 10 | pub fn is_ci() -> bool { |
9 | option_env!("CI").is_some() | 11 | option_env!("CI").is_some() |
@@ -25,6 +27,27 @@ pub fn timeit(label: &'static str) -> impl Drop { | |||
25 | Guard { label, start: Instant::now() } | 27 | Guard { label, start: Instant::now() } |
26 | } | 28 | } |
27 | 29 | ||
30 | /// Prints backtrace to stderr, useful for debugging. | ||
31 | #[cfg(feature = "backtrace")] | ||
32 | pub fn print_backtrace() { | ||
33 | let bt = backtrace::Backtrace::new(); | ||
34 | eprintln!("{:?}", bt); | ||
35 | } | ||
36 | #[cfg(not(feature = "backtrace"))] | ||
37 | pub fn print_backtrace() { | ||
38 | eprintln!( | ||
39 | r#"Enable the backtrace feature. | ||
40 | Uncomment `default = [ "backtrace" ]` in `crates/stdx/Cargo.toml`. | ||
41 | "# | ||
42 | ); | ||
43 | } | ||
44 | |||
45 | pub fn to_lower_snake_case(s: &str) -> String { | ||
46 | to_snake_case(s, char::to_ascii_lowercase) | ||
47 | } | ||
48 | pub fn to_upper_snake_case(s: &str) -> String { | ||
49 | to_snake_case(s, char::to_ascii_uppercase) | ||
50 | } | ||
28 | fn to_snake_case<F: Fn(&char) -> char>(s: &str, change_case: F) -> String { | 51 | fn to_snake_case<F: Fn(&char) -> char>(s: &str, change_case: F) -> String { |
29 | let mut buf = String::with_capacity(s.len()); | 52 | let mut buf = String::with_capacity(s.len()); |
30 | let mut prev = false; | 53 | let mut prev = false; |
@@ -43,14 +66,6 @@ fn to_snake_case<F: Fn(&char) -> char>(s: &str, change_case: F) -> String { | |||
43 | buf | 66 | buf |
44 | } | 67 | } |
45 | 68 | ||
46 | pub fn to_lower_snake_case(s: &str) -> String { | ||
47 | to_snake_case(s, char::to_ascii_lowercase) | ||
48 | } | ||
49 | |||
50 | pub fn to_upper_snake_case(s: &str) -> String { | ||
51 | to_snake_case(s, char::to_ascii_uppercase) | ||
52 | } | ||
53 | |||
54 | pub fn replace(buf: &mut String, from: char, to: &str) { | 69 | pub fn replace(buf: &mut String, from: char, to: &str) { |
55 | if !buf.contains(from) { | 70 | if !buf.contains(from) { |
56 | return; | 71 | return; |
@@ -117,7 +132,12 @@ impl<'a> Iterator for LinesWithEnds<'a> { | |||
117 | } | 132 | } |
118 | } | 133 | } |
119 | 134 | ||
120 | // https://github.com/rust-lang/rust/issues/73831 | 135 | /// Returns `idx` such that: |
136 | /// | ||
137 | /// ∀ x in slice[..idx]: pred(x) | ||
138 | /// && ∀ x in slice[idx..]: !pred(x) | ||
139 | /// | ||
140 | /// https://github.com/rust-lang/rust/issues/73831 | ||
121 | pub fn partition_point<T, P>(slice: &[T], mut pred: P) -> usize | 141 | pub fn partition_point<T, P>(slice: &[T], mut pred: P) -> usize |
122 | where | 142 | where |
123 | P: FnMut(&T) -> bool, | 143 | P: FnMut(&T) -> bool, |
@@ -147,6 +167,36 @@ where | |||
147 | left | 167 | left |
148 | } | 168 | } |
149 | 169 | ||
170 | pub fn equal_range_by<T, F>(slice: &[T], mut key: F) -> ops::Range<usize> | ||
171 | where | ||
172 | F: FnMut(&T) -> Ordering, | ||
173 | { | ||
174 | let start = partition_point(slice, |it| key(it) == Ordering::Less); | ||
175 | let len = partition_point(&slice[start..], |it| key(it) == Ordering::Equal); | ||
176 | start..start + len | ||
177 | } | ||
178 | |||
179 | pub struct JodChild(pub process::Child); | ||
180 | |||
181 | impl ops::Deref for JodChild { | ||
182 | type Target = process::Child; | ||
183 | fn deref(&self) -> &process::Child { | ||
184 | &self.0 | ||
185 | } | ||
186 | } | ||
187 | |||
188 | impl ops::DerefMut for JodChild { | ||
189 | fn deref_mut(&mut self) -> &mut process::Child { | ||
190 | &mut self.0 | ||
191 | } | ||
192 | } | ||
193 | |||
194 | impl Drop for JodChild { | ||
195 | fn drop(&mut self) { | ||
196 | let _ = self.0.kill(); | ||
197 | } | ||
198 | } | ||
199 | |||
150 | #[cfg(test)] | 200 | #[cfg(test)] |
151 | mod tests { | 201 | mod tests { |
152 | use super::*; | 202 | use super::*; |