use derive_more::From;
use nbytes::bytes;
use std::num::NonZeroUsize;
use strum::{EnumIter, EnumString, IntoEnumIterator};
#[cfg_attr(feature = "std", derive(Debug))]
#[derive(Clone, Copy, From, PartialEq, Eq)]
pub enum ChunkPolicy {
FixedSize(WellKnownChunkSize),
}
impl ChunkPolicy {
pub fn fixed_size(&self) -> Option<usize> {
match self {
Self::FixedSize(well_known) => Some(*well_known as usize),
}
}
}
impl Default for ChunkPolicy {
fn default() -> Self {
Self::FixedSize(WellKnownChunkSize::default())
}
}
impl From<ChunkPolicy> for NonZeroUsize {
fn from(policy: ChunkPolicy) -> NonZeroUsize {
match policy {
ChunkPolicy::FixedSize(size) => unsafe { NonZeroUsize::new_unchecked(size as usize) },
}
}
}
#[cfg_attr(feature = "std", derive(Debug))]
#[derive(Default, Clone, Copy, PartialEq, Eq, strum::Display, EnumIter, EnumString)]
#[repr(u32)]
pub enum WellKnownChunkSize {
#[strum(serialize = "32B", ascii_case_insensitive)]
F32B = 32,
#[strum(serialize = "512B", ascii_case_insensitive)]
F512B = 512,
#[strum(serialize = "1KiB", ascii_case_insensitive)]
F1KiB = bytes!(1; KiB),
#[strum(serialize = "16KiB", ascii_case_insensitive)]
F16KiB = bytes!(16; KiB),
#[default]
#[strum(serialize = "256KiB", ascii_case_insensitive)]
F256KiB = bytes!(256; KiB),
#[strum(serialize = "1MiB", ascii_case_insensitive)]
F1MiB = bytes!(1; MiB),
#[cfg(feature = "jumbo-chunks")]
#[strum(serialize = "8MiB", ascii_case_insensitive)]
F8MiB = bytes!(8; MiB),
#[cfg(feature = "jumbo-chunks")]
#[strum(serialize = "32MiB", ascii_case_insensitive)]
F32MiB = bytes!(32; MiB),
#[cfg(feature = "jumbo-chunks")]
#[strum(serialize = "128MiB", ascii_case_insensitive)]
F128MiB = bytes!(128; MiB),
#[cfg(feature = "jumbo-chunks")]
#[strum(serialize = "256MiB", ascii_case_insensitive)]
F256MiB = bytes!(256; MiB),
#[cfg(feature = "jumbo-chunks")]
#[strum(serialize = "512MiB", ascii_case_insensitive)]
F512MiB = bytes!(512; MiB),
}
fn valid_chunk_size_args() -> String {
WellKnownChunkSize::iter().map(|wk| wk.to_string()).collect::<Vec<_>>().join(", ")
}
impl std::str::FromStr for ChunkPolicy {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let wkcs: WellKnownChunkSize = s
.parse()
.map_err(|_| format!("Invalid `ChunkSize`, valid options are: {}", valid_chunk_size_args()))?;
Ok(ChunkPolicy::FixedSize(wkcs))
}
}