pub mod bytes; pub mod content_disposition; pub mod debug; pub mod defer; pub mod hash; pub mod html; pub mod json; pub mod mutex_map; pub mod string; pub mod sys; mod tests; pub mod time; use std::cmp::{self, Ordering}; pub use bytes::{increment, u64_from_bytes, u64_from_u8, u64_from_u8x8}; pub use debug::slice_truncated as debug_slice_truncated; pub use hash::calculate_hash; pub use html::Escape as HtmlEscape; pub use json::{deserialize_from_str, to_canonical_object}; pub use mutex_map::MutexMap; pub use string::{random_string, str_from_bytes, string_from_bytes}; pub use sys::available_parallelism; pub use time::millis_since_unix_epoch; use crate::Result; pub fn clamp(val: T, min: T, max: T) -> T { cmp::min(cmp::max(val, min), max) } /// Boilerplate for wraps which are typed to never error. /// /// * #[must_use] #[inline(always)] pub fn unwrap_infallible(result: Result) -> T { match result { Ok(val) => val, Err(err) => match err {}, } } #[must_use] pub fn generate_keypair() -> Vec { let mut value = random_string(8).as_bytes().to_vec(); value.push(0xFF); value.extend_from_slice( &ruma::signatures::Ed25519KeyPair::generate().expect("Ed25519KeyPair generation always works (?)"), ); value } #[allow(clippy::impl_trait_in_params)] pub fn common_elements( mut iterators: impl Iterator>>, check_order: impl Fn(&[u8], &[u8]) -> Ordering, ) -> Option>> { let first_iterator = iterators.next()?; let mut other_iterators = iterators.map(Iterator::peekable).collect::>(); Some(first_iterator.filter(move |target| { other_iterators.iter_mut().all(|it| { while let Some(element) = it.peek() { match check_order(element, target) { Ordering::Greater => return false, // We went too far Ordering::Equal => return true, // Element is in both iters Ordering::Less => { // Keep searching it.next(); }, } } false }) })) }