use std::any::Any;
use std::collections::{HashMap, HashSet};
use std::hash::Hash;
use std::sync::{Arc, Condvar, Mutex};
use std::time::{Duration, SystemTime};
pub type Array<T> = Vec<T>;
pub type Data = Vec<u8>;
pub type Date = SystemTime;
pub type Dictionary<K, V> = HashMap<K, V>;
pub type Set<T> = HashSet<T>;
pub type String = std::string::String;
pub type Enumerator<T> = std::vec::IntoIter<T>;
pub trait Locking<T> {
fn with_lock<R>(&self, operation: impl FnOnce(&mut T) -> R) -> R;
}
impl<T> Locking<T> for Mutex<T> {
fn with_lock<R>(&self, operation: impl FnOnce(&mut T) -> R) -> R {
let mut value = self.lock().unwrap_or_else(|error| error.into_inner());
operation(&mut value)
}
}
#[must_use]
pub fn enumerate<T>(values: Array<T>) -> Enumerator<T> {
values.into_iter()
}
#[must_use]
pub fn append_string(left: &str, right: &str) -> String {
let mut value = String::with_capacity(left.len().saturating_add(right.len()));
value.push_str(left);
value.push_str(right);
value
}
#[must_use]
pub fn date_with_time_interval_since_now(seconds: f64) -> Option<Date> {
if !seconds.is_finite() {
return None;
}
let duration = Duration::from_secs_f64(seconds.abs());
if seconds.is_sign_negative() {
SystemTime::now().checked_sub(duration)
} else {
SystemTime::now().checked_add(duration)
}
}
#[derive(Clone)]
pub struct Value(Arc<dyn Any + Send + Sync>);
impl Value {
#[must_use]
pub fn new<T: Any + Send + Sync>(value: T) -> Self {
Self(Arc::new(value))
}
#[must_use]
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
self.0.downcast_ref()
}
}
pub trait Copying: Clone {
#[must_use]
fn copy_owned(&self) -> Self {
self.clone()
}
}
impl<T: Clone> Copying for T {}
pub trait Object: Clone + Eq + Hash {
#[must_use]
fn object_hash(&self) -> u64 {
hash_value(self)
}
#[must_use]
fn object_is_equal(&self, other: &Self) -> bool {
self == other
}
}
impl<T: Clone + Eq + Hash> Object for T {}
pub trait SecureCoding: Clone + Send + Sync {}
impl<T: Clone + Send + Sync> SecureCoding for T {}
#[derive(Default)]
pub struct Condition {
state: Mutex<bool>,
condition: Condvar,
}
impl Condition {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn wait(&self) {
let mut state = self.state.lock().unwrap_or_else(|error| error.into_inner());
while !*state {
state = self
.condition
.wait(state)
.unwrap_or_else(|error| error.into_inner());
}
*state = false;
}
#[must_use]
pub fn wait_until(&self, deadline: Date) -> bool {
let duration = deadline
.duration_since(SystemTime::now())
.unwrap_or(Duration::ZERO);
let state = self.state.lock().unwrap_or_else(|error| error.into_inner());
let (mut state, timeout) = self
.condition
.wait_timeout_while(state, duration, |ready| !*ready)
.unwrap_or_else(|error| error.into_inner());
let signalled = *state && !timeout.timed_out();
if signalled {
*state = false;
}
signalled
}
pub fn signal(&self) {
*self.state.lock().unwrap_or_else(|error| error.into_inner()) = true;
self.condition.notify_one();
}
pub fn broadcast(&self) {
*self.state.lock().unwrap_or_else(|error| error.into_inner()) = true;
self.condition.notify_all();
}
}
pub trait StringExt {
#[must_use]
fn character(&self, index: usize) -> Option<char>;
#[must_use]
fn range_of(&self, needle: &str) -> Option<std::ops::Range<usize>>;
#[must_use]
fn compare_case_insensitive(&self, other: &str) -> std::cmp::Ordering;
}
impl StringExt for str {
fn character(&self, index: usize) -> Option<char> {
self.chars().nth(index)
}
fn range_of(&self, needle: &str) -> Option<std::ops::Range<usize>> {
self.find(needle).map(|start| start..start + needle.len())
}
fn compare_case_insensitive(&self, other: &str) -> std::cmp::Ordering {
self.to_lowercase().cmp(&other.to_lowercase())
}
}
#[must_use]
pub fn is_equal<T: Eq>(left: &T, right: &T) -> bool {
left == right
}
#[must_use]
pub fn hash_value<T: Hash>(value: &T) -> u64 {
use std::hash::Hasher;
let mut hasher = std::collections::hash_map::DefaultHasher::new();
value.hash(&mut hasher);
hasher.finish()
}