#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct Pid(u16);
impl Pid {
pub const MASK: u16 = 0x1FFF;
#[must_use]
pub const fn new(value: u16) -> Self {
Self(value & Self::MASK)
}
#[must_use]
pub const fn from_wire_masked(value: u16) -> Self {
Self(value & Self::MASK)
}
pub const fn try_new(value: u16) -> Result<Self, PidOutOfRange> {
if value > Self::MASK {
Err(PidOutOfRange { value })
} else {
Ok(Self(value))
}
}
#[must_use]
pub const fn value(self) -> u16 {
self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub struct PidOutOfRange {
pub value: u16,
}
impl core::fmt::Display for PidOutOfRange {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"PID 0x{:04X} exceeds the 13-bit range 0x0000..=0x1FFF",
self.value
)
}
}
impl core::error::Error for PidOutOfRange {}
impl TryFrom<u16> for Pid {
type Error = PidOutOfRange;
fn try_from(value: u16) -> Result<Self, Self::Error> {
Self::try_new(value)
}
}
impl From<Pid> for u16 {
fn from(pid: Pid) -> Self {
pid.0
}
}
impl core::fmt::Debug for Pid {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "Pid(0x{:04X})", self.0)
}
}
impl core::fmt::UpperHex for Pid {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
core::fmt::UpperHex::fmt(&self.0, f)
}
}
impl core::fmt::LowerHex for Pid {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
core::fmt::LowerHex::fmt(&self.0, f)
}
}
impl core::fmt::Display for Pid {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "0x{:04X}", self.0)
}
}
pub mod well_known {
use super::Pid;
pub const PAT: Pid = Pid::new(0x0000);
pub const CAT: Pid = Pid::new(0x0001);
pub const TSDT: Pid = Pid::new(0x0002);
pub const IPMP_CIT: Pid = Pid::new(0x0003);
pub const NIT: Pid = Pid::new(0x0010);
pub const SDT_BAT: Pid = Pid::new(0x0011);
pub const EIT: Pid = Pid::new(0x0012);
pub const RST: Pid = Pid::new(0x0013);
pub const TDT_TOT: Pid = Pid::new(0x0014);
pub const NETWORK_SYNC: Pid = Pid::new(0x0015);
pub const RNT: Pid = Pid::new(0x0016);
pub const SAT: Pid = Pid::new(0x001B);
pub const INBAND_SIGNALLING: Pid = Pid::new(0x001C);
pub const MEASUREMENT: Pid = Pid::new(0x001D);
pub const DIT: Pid = Pid::new(0x001E);
pub const SIT: Pid = Pid::new(0x001F);
pub const ATSC_PSIP: Pid = Pid::new(0x1FFB);
pub const NULL: Pid = Pid::new(0x1FFF);
}