#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MailboxCapacity(u32);
impl MailboxCapacity {
pub const MIN: u32 = 1;
pub const MAX: u32 = 1 << 20;
pub const DEFAULT: MailboxCapacity = MailboxCapacity(256);
pub const fn new(value: u32) -> Option<Self> {
if value < Self::MIN || value > Self::MAX {
None
} else {
Some(Self(value))
}
}
#[inline]
pub const fn get(self) -> usize {
self.0 as usize
}
#[inline]
pub const fn get_u32(self) -> u32 {
self.0
}
}
impl Default for MailboxCapacity {
fn default() -> Self {
Self::DEFAULT
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MailboxBytes(usize);
impl MailboxBytes {
pub const MIN: usize = 1 << 10;
pub const MAX: usize = 1 << 30;
pub const DEFAULT: MailboxBytes = MailboxBytes(1 << 22);
pub const fn new(value: usize) -> Option<Self> {
if value < Self::MIN || value > Self::MAX {
None
} else {
Some(Self(value))
}
}
#[inline]
pub const fn get(self) -> usize {
self.0
}
}
impl Default for MailboxBytes {
fn default() -> Self {
Self::DEFAULT
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rejects_zero_and_over_max() -> Result<(), &'static str> {
assert!(MailboxCapacity::new(0).is_none());
assert!(MailboxCapacity::new(MailboxCapacity::MAX + 1).is_none());
let min = MailboxCapacity::new(1).ok_or("min capacity")?;
assert_eq!(min.get(), 1);
let max = MailboxCapacity::new(MailboxCapacity::MAX).ok_or("max capacity")?;
assert_eq!(max.get_u32(), MailboxCapacity::MAX);
Ok(())
}
#[test]
fn default_is_compile_time_valid() {
assert_eq!(MailboxCapacity::DEFAULT.get(), 256);
assert!(MailboxCapacity::new(256).is_some());
}
#[test]
fn byte_budget_rejects_out_of_range() -> Result<(), &'static str> {
assert!(MailboxBytes::new(0).is_none());
assert!(MailboxBytes::new(MailboxBytes::MIN - 1).is_none());
assert!(MailboxBytes::new(MailboxBytes::MAX + 1).is_none());
let min = MailboxBytes::new(MailboxBytes::MIN).ok_or("min bytes")?;
assert_eq!(min.get(), MailboxBytes::MIN);
Ok(())
}
#[test]
fn byte_budget_default_holds_a_full_scalar_inbox() {
let worst = MailboxCapacity::DEFAULT.get() * std::mem::size_of::<crate::Value>();
assert!(MailboxBytes::DEFAULT.get() > worst);
}
#[test]
fn byte_budget_default_fits_one_max_hop() {
const MAX_BLOB: usize = 1_048_576;
let biggest = crate::Value::bytes(vec![0u8; MAX_BLOB]);
assert!(biggest.memory_size() <= MailboxBytes::DEFAULT.get());
}
}