use super::ValidationError;
use std::fmt;
pub const PASID_MAX: u32 = 0xF_FFFF;
fn format_with_underscores(value: u32) -> String {
let s = value.to_string();
let bytes = s.as_bytes();
let len = bytes.len();
let mut result = String::new();
for (i, &byte) in bytes.iter().enumerate() {
if i > 0 && (len - i) % 3 == 0 {
result.push('_');
}
result.push(byte as char);
}
result
}
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PASID(u32);
impl PASID {
pub fn new(value: u32) -> Result<Self, ValidationError> {
if value > PASID_MAX {
return Err(ValidationError::new(
"PASID",
&format!("0x{value:X}"),
"must be <= 0xF_FFFF (20-bit maximum)",
));
}
Ok(Self(value))
}
#[must_use]
pub const fn as_u32(self) -> u32 {
self.0
}
}
impl fmt::Display for PASID {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "PASID({})", format_with_underscores(self.0))
}
}
impl TryFrom<u32> for PASID {
type Error = ValidationError;
fn try_from(value: u32) -> Result<Self, Self::Error> {
Self::new(value)
}
}
impl From<PASID> for u32 {
fn from(pasid: PASID) -> Self {
pasid.0
}
}