#[cfg(feature = "std")]
pub(crate) use std::collections::HashMap;
#[cfg(feature = "std")]
pub(crate) use std::collections::hash_map::Iter as HashMapIter;
#[cfg(not(feature = "std"))]
pub(crate) use hashbrown::HashMap;
#[cfg(not(feature = "std"))]
pub(crate) use hashbrown::hash_map::Iter as HashMapIter;
#[cfg(feature = "std")]
mod lock {
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
pub(crate) fn read_lock<T>(
lock: &RwLock<T>,
) -> Result<RwLockReadGuard<'_, T>, alloc::string::String> {
lock.read()
.map_err(|e| alloc::format!("RwLock poisoned: {e}"))
}
pub(crate) fn write_lock<T>(
lock: &RwLock<T>,
) -> Result<RwLockWriteGuard<'_, T>, alloc::string::String> {
lock.write()
.map_err(|e| alloc::format!("RwLock poisoned: {e}"))
}
pub(crate) fn read_lock_recover<T>(lock: &RwLock<T>) -> RwLockReadGuard<'_, T> {
match lock.read() {
Ok(guard) => guard,
Err(poisoned) => {
tracing::warn!("RwLock poisoned on read; recovering inner data");
poisoned.into_inner()
}
}
}
pub(crate) fn write_lock_recover<T>(lock: &RwLock<T>) -> RwLockWriteGuard<'_, T> {
match lock.write() {
Ok(guard) => guard,
Err(poisoned) => {
tracing::warn!("RwLock poisoned on write; recovering inner data");
poisoned.into_inner()
}
}
}
}
#[cfg(not(feature = "std"))]
mod lock {
use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};
pub(crate) fn read_lock<T>(
lock: &RwLock<T>,
) -> Result<RwLockReadGuard<'_, T>, alloc::string::String> {
Result::<_, core::convert::Infallible>::Ok(lock.read()).map_err(|e| match e {})
}
pub(crate) fn write_lock<T>(
lock: &RwLock<T>,
) -> Result<RwLockWriteGuard<'_, T>, alloc::string::String> {
Result::<_, core::convert::Infallible>::Ok(lock.write()).map_err(|e| match e {})
}
pub(crate) fn read_lock_recover<T>(lock: &RwLock<T>) -> RwLockReadGuard<'_, T> {
lock.read()
}
pub(crate) fn write_lock_recover<T>(lock: &RwLock<T>) -> RwLockWriteGuard<'_, T> {
lock.write()
}
}
#[cfg(feature = "std")]
pub(crate) use std::sync::OnceLock;
#[cfg(feature = "std")]
pub(crate) use std::sync::RwLock;
pub(crate) use lock::{read_lock, read_lock_recover, write_lock, write_lock_recover};
#[cfg(not(feature = "std"))]
pub(crate) use spin::RwLock;
#[cfg(not(feature = "std"))]
#[derive(Debug, Default)]
pub(crate) struct OnceLock<T>(spin::Once<T>);
#[cfg(not(feature = "std"))]
impl<T> OnceLock<T> {
pub const fn new() -> Self {
Self(spin::Once::new())
}
pub fn get_or_init<F>(&self, f: F) -> &T
where
F: FnOnce() -> T,
{
self.0.call_once(f)
}
}