Skip to main content

ipld_car/config/
chunck_policy.rs

1use derive_more::From;
2use nbytes::bytes;
3use std::num::NonZeroUsize;
4use strum::{EnumIter, EnumString, IntoEnumIterator};
5
6/// How chunks are defined.
7///
8/// Only fixed-size chunks are currently supported.
9#[cfg_attr(feature = "std", derive(Debug))]
10#[derive(Clone, Copy, From, PartialEq, Eq)]
11pub enum ChunkPolicy {
12	FixedSize(WellKnownChunkSize),
13	// Rabin
14}
15
16impl ChunkPolicy {
17	/// Returns the fixed chunk size in bytes if configured.
18	pub fn fixed_size(&self) -> Option<usize> {
19		match self {
20			Self::FixedSize(well_known) => Some(*well_known as usize),
21			// _ => None,
22		}
23	}
24}
25
26impl Default for ChunkPolicy {
27	fn default() -> Self {
28		Self::FixedSize(WellKnownChunkSize::default())
29	}
30}
31
32/// Converts chunk policy to NonZeroUsize for APIs requiring non-zero sizes.
33impl From<ChunkPolicy> for NonZeroUsize {
34	fn from(policy: ChunkPolicy) -> NonZeroUsize {
35		match policy {
36			ChunkPolicy::FixedSize(size) => unsafe { NonZeroUsize::new_unchecked(size as usize) },
37		}
38	}
39}
40
41/// Well-known chunk sizes for fixed-size chunks.
42///
43/// Chunk sizes larger than `256KiB` need the feature `jumbo-chunks`.
44#[cfg_attr(feature = "std", derive(Debug))]
45#[derive(Default, Clone, Copy, PartialEq, Eq, strum::Display, EnumIter, EnumString)]
46#[repr(u32)]
47pub enum WellKnownChunkSize {
48	#[strum(serialize = "32B", ascii_case_insensitive)]
49	F32B = 32,
50	#[strum(serialize = "512B", ascii_case_insensitive)]
51	F512B = 512,
52	#[strum(serialize = "1KiB", ascii_case_insensitive)]
53	F1KiB = bytes!(1; KiB),
54	#[strum(serialize = "16KiB", ascii_case_insensitive)]
55	F16KiB = bytes!(16; KiB),
56	#[default]
57	#[strum(serialize = "256KiB", ascii_case_insensitive)]
58	F256KiB = bytes!(256; KiB),
59	#[strum(serialize = "1MiB", ascii_case_insensitive)]
60	F1MiB = bytes!(1; MiB),
61	#[cfg(feature = "jumbo-chunks")]
62	#[strum(serialize = "8MiB", ascii_case_insensitive)]
63	F8MiB = bytes!(8; MiB),
64	#[cfg(feature = "jumbo-chunks")]
65	#[strum(serialize = "32MiB", ascii_case_insensitive)]
66	F32MiB = bytes!(32; MiB),
67	#[cfg(feature = "jumbo-chunks")]
68	#[strum(serialize = "128MiB", ascii_case_insensitive)]
69	F128MiB = bytes!(128; MiB),
70	#[cfg(feature = "jumbo-chunks")]
71	#[strum(serialize = "256MiB", ascii_case_insensitive)]
72	F256MiB = bytes!(256; MiB),
73	#[cfg(feature = "jumbo-chunks")]
74	#[strum(serialize = "512MiB", ascii_case_insensitive)]
75	F512MiB = bytes!(512; MiB),
76}
77
78fn valid_chunk_size_args() -> String {
79	WellKnownChunkSize::iter().map(|wk| wk.to_string()).collect::<Vec<_>>().join(", ")
80}
81
82impl std::str::FromStr for ChunkPolicy {
83	type Err = String;
84
85	fn from_str(s: &str) -> Result<Self, Self::Err> {
86		let wkcs: WellKnownChunkSize = s
87			.parse()
88			.map_err(|_| format!("Invalid `ChunkSize`, valid options are: {}", valid_chunk_size_args()))?;
89		Ok(ChunkPolicy::FixedSize(wkcs))
90	}
91}