use std::collections::HashMap;
use std::fmt::Display;
use std::fmt::UpperHex;
use num_enum::TryFromPrimitive;
use crate::prelude::*;
use crate::util::fmt::format_bytes;
use crate::util::fmt::typename;
pub fn vec_with_capacity<T>(count: u32) -> Result<Vec<T>> {
const FAILSAFE_SIZE: usize = 10_000_000; let count = count as usize;
let implied_size = size_of::<T>().saturating_mul(count);
if implied_size > FAILSAFE_SIZE {
bail!(
"{} count {} implies data size {} which exceeds failsafe size {}",
typename::<T>(),
count,
format_bytes(implied_size),
format_bytes(FAILSAFE_SIZE),
);
}
Ok(Vec::with_capacity(count))
}
pub fn hashmap_with_capacity<K, V>(count: u32) -> Result<HashMap<K, V>> {
const FAILSAFE_SIZE: usize = 100_000; let count = count as usize;
let entry_size = size_of::<(K, V)>() + size_of::<usize>() * 3;
let estimated_size = entry_size.saturating_mul(count);
if estimated_size > FAILSAFE_SIZE {
bail!(
"HashMap<{}, {}> with capacity {} would use ~{} which exceeds failsafe size {}",
typename::<K>(),
typename::<V>(),
count,
format_bytes(estimated_size),
format_bytes(FAILSAFE_SIZE),
);
}
Ok(HashMap::with_capacity(count))
}
pub fn num_enum_from<I, N>(value: I) -> Result<N>
where
I: Display + UpperHex + Copy,
N: TryFromPrimitive + TryFrom<I>,
{
match value.try_into() {
Ok(val) => Ok(val),
Err(_) => bail!(
"Invalid {0} {1} (0x{1:0width$X})",
typename::<N>(),
value,
width = size_of::<I>() * 2,
),
}
}