#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[rustfmt::skip] #[non_exhaustive]
pub enum DeviceRestrictions {
RestrictGroup0 = 0b00,
RestrictGroup1 = 0b01,
RestrictGroup2 = 0b10,
None = 0b11,
}
impl DeviceRestrictions {
#[must_use]
pub fn from_bits(v: u8) -> Self {
match v & 0b11 {
0b00 => Self::RestrictGroup0,
0b01 => Self::RestrictGroup1,
0b10 => Self::RestrictGroup2,
_ => Self::None,
}
}
#[must_use]
pub const fn bits(self) -> u8 {
self as u8
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::RestrictGroup0 => "restricted for device group 0",
Self::RestrictGroup1 => "restricted for device group 1",
Self::RestrictGroup2 => "restricted for device group 2",
Self::None => "no device restrictions",
}
}
}
dvb_common::impl_spec_display!(DeviceRestrictions);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[allow(missing_docs)] #[rustfmt::skip] #[non_exhaustive]
pub enum SegmentationUpidType {
NotUsed, UserDefinedDeprecated, Isci, AdId, Umid, IsanDeprecated, Isan, Tid, Ti, Adi, Eidr, AtscContentIdentifier, Mpu, Mid, AdsInformation, Uri, Uuid, Scr, Reserved(u8),
}
#[allow(missing_docs)]
impl SegmentationUpidType {
#[must_use]
pub fn from_u8(v: u8) -> Self {
match v {
0x00 => Self::NotUsed,
0x01 => Self::UserDefinedDeprecated,
0x02 => Self::Isci,
0x03 => Self::AdId,
0x04 => Self::Umid,
0x05 => Self::IsanDeprecated,
0x06 => Self::Isan,
0x07 => Self::Tid,
0x08 => Self::Ti,
0x09 => Self::Adi,
0x0A => Self::Eidr,
0x0B => Self::AtscContentIdentifier,
0x0C => Self::Mpu,
0x0D => Self::Mid,
0x0E => Self::AdsInformation,
0x0F => Self::Uri,
0x10 => Self::Uuid,
0x11 => Self::Scr,
other => Self::Reserved(other),
}
}
#[must_use]
pub const fn to_u8(self) -> u8 {
match self {
Self::NotUsed => 0x00,
Self::UserDefinedDeprecated => 0x01,
Self::Isci => 0x02,
Self::AdId => 0x03,
Self::Umid => 0x04,
Self::IsanDeprecated => 0x05,
Self::Isan => 0x06,
Self::Tid => 0x07,
Self::Ti => 0x08,
Self::Adi => 0x09,
Self::Eidr => 0x0A,
Self::AtscContentIdentifier => 0x0B,
Self::Mpu => 0x0C,
Self::Mid => 0x0D,
Self::AdsInformation => 0x0E,
Self::Uri => 0x0F,
Self::Uuid => 0x10,
Self::Scr => 0x11,
Self::Reserved(v) => v,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::NotUsed => "Not Used",
Self::UserDefinedDeprecated => "User Defined (deprecated)",
Self::Isci => "ISCI",
Self::AdId => "Ad-ID",
Self::Umid => "UMID",
Self::IsanDeprecated => "ISAN (deprecated)",
Self::Isan => "ISAN",
Self::Tid => "TID",
Self::Ti => "TI",
Self::Adi => "ADI",
Self::Eidr => "EIDR",
Self::AtscContentIdentifier => "ATSC Content Identifier",
Self::Mpu => "MPU()",
Self::Mid => "MID()",
Self::AdsInformation => "ADS Information",
Self::Uri => "URI",
Self::Uuid => "UUID",
Self::Scr => "SCR",
Self::Reserved(_) => "reserved",
}
}
}
dvb_common::impl_spec_display!(SegmentationUpidType, Reserved);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[allow(missing_docs)] #[rustfmt::skip] #[non_exhaustive]
pub enum SegmentationTypeId {
NotIndicated, ContentIdentification, Private, ProgramStart, ProgramEnd, ProgramEarlyTermination, ProgramBreakaway, ProgramResumption, ProgramRunoverPlanned, ProgramRunoverUnplanned, ProgramOverlapStart, ProgramBlackoutOverride, ProgramJoin, ProgramImmediateResumption, ChapterStart, ChapterEnd, BreakStart, BreakEnd, OpeningCreditStart, OpeningCreditEnd, ClosingCreditStart, ClosingCreditEnd, ProviderAdvertisementStart, ProviderAdvertisementEnd, DistributorAdvertisementStart, DistributorAdvertisementEnd, ProviderPlacementOpportunityStart, ProviderPlacementOpportunityEnd, DistributorPlacementOpportunityStart, DistributorPlacementOpportunityEnd, ProviderOverlayPlacementOpportunityStart, ProviderOverlayPlacementOpportunityEnd, DistributorOverlayPlacementOpportunityStart, DistributorOverlayPlacementOpportunityEnd, ProviderPromoStart, ProviderPromoEnd, DistributorPromoStart, DistributorPromoEnd, UnscheduledEventStart, UnscheduledEventEnd, AlternateContentOpportunityStart, AlternateContentOpportunityEnd, ProviderAdBlockStart, ProviderAdBlockEnd, DistributorAdBlockStart, DistributorAdBlockEnd, NetworkStart, NetworkEnd, Reserved(u8),
}
#[allow(missing_docs)]
#[rustfmt::skip] impl SegmentationTypeId {
#[must_use]
pub fn from_u8(v: u8) -> Self {
match v {
0x00 => Self::NotIndicated,
0x01 => Self::ContentIdentification,
0x02 => Self::Private,
0x10 => Self::ProgramStart,
0x11 => Self::ProgramEnd,
0x12 => Self::ProgramEarlyTermination,
0x13 => Self::ProgramBreakaway,
0x14 => Self::ProgramResumption,
0x15 => Self::ProgramRunoverPlanned,
0x16 => Self::ProgramRunoverUnplanned,
0x17 => Self::ProgramOverlapStart,
0x18 => Self::ProgramBlackoutOverride,
0x19 => Self::ProgramJoin,
0x1A => Self::ProgramImmediateResumption,
0x20 => Self::ChapterStart,
0x21 => Self::ChapterEnd,
0x22 => Self::BreakStart,
0x23 => Self::BreakEnd,
0x24 => Self::OpeningCreditStart,
0x25 => Self::OpeningCreditEnd,
0x26 => Self::ClosingCreditStart,
0x27 => Self::ClosingCreditEnd,
0x30 => Self::ProviderAdvertisementStart,
0x31 => Self::ProviderAdvertisementEnd,
0x32 => Self::DistributorAdvertisementStart,
0x33 => Self::DistributorAdvertisementEnd,
0x34 => Self::ProviderPlacementOpportunityStart,
0x35 => Self::ProviderPlacementOpportunityEnd,
0x36 => Self::DistributorPlacementOpportunityStart,
0x37 => Self::DistributorPlacementOpportunityEnd,
0x38 => Self::ProviderOverlayPlacementOpportunityStart,
0x39 => Self::ProviderOverlayPlacementOpportunityEnd,
0x3A => Self::DistributorOverlayPlacementOpportunityStart,
0x3B => Self::DistributorOverlayPlacementOpportunityEnd,
0x3C => Self::ProviderPromoStart,
0x3D => Self::ProviderPromoEnd,
0x3E => Self::DistributorPromoStart,
0x3F => Self::DistributorPromoEnd,
0x40 => Self::UnscheduledEventStart,
0x41 => Self::UnscheduledEventEnd,
0x42 => Self::AlternateContentOpportunityStart,
0x43 => Self::AlternateContentOpportunityEnd,
0x44 => Self::ProviderAdBlockStart,
0x45 => Self::ProviderAdBlockEnd,
0x46 => Self::DistributorAdBlockStart,
0x47 => Self::DistributorAdBlockEnd,
0x50 => Self::NetworkStart,
0x51 => Self::NetworkEnd,
other => Self::Reserved(other),
}
}
#[must_use]
pub const fn to_u8(self) -> u8 {
match self {
Self::NotIndicated => 0x00,
Self::ContentIdentification => 0x01,
Self::Private => 0x02,
Self::ProgramStart => 0x10,
Self::ProgramEnd => 0x11,
Self::ProgramEarlyTermination => 0x12,
Self::ProgramBreakaway => 0x13,
Self::ProgramResumption => 0x14,
Self::ProgramRunoverPlanned => 0x15,
Self::ProgramRunoverUnplanned => 0x16,
Self::ProgramOverlapStart => 0x17,
Self::ProgramBlackoutOverride => 0x18,
Self::ProgramJoin => 0x19,
Self::ProgramImmediateResumption => 0x1A,
Self::ChapterStart => 0x20,
Self::ChapterEnd => 0x21,
Self::BreakStart => 0x22,
Self::BreakEnd => 0x23,
Self::OpeningCreditStart => 0x24,
Self::OpeningCreditEnd => 0x25,
Self::ClosingCreditStart => 0x26,
Self::ClosingCreditEnd => 0x27,
Self::ProviderAdvertisementStart => 0x30,
Self::ProviderAdvertisementEnd => 0x31,
Self::DistributorAdvertisementStart => 0x32,
Self::DistributorAdvertisementEnd => 0x33,
Self::ProviderPlacementOpportunityStart => 0x34,
Self::ProviderPlacementOpportunityEnd => 0x35,
Self::DistributorPlacementOpportunityStart => 0x36,
Self::DistributorPlacementOpportunityEnd => 0x37,
Self::ProviderOverlayPlacementOpportunityStart => 0x38,
Self::ProviderOverlayPlacementOpportunityEnd => 0x39,
Self::DistributorOverlayPlacementOpportunityStart => 0x3A,
Self::DistributorOverlayPlacementOpportunityEnd => 0x3B,
Self::ProviderPromoStart => 0x3C,
Self::ProviderPromoEnd => 0x3D,
Self::DistributorPromoStart => 0x3E,
Self::DistributorPromoEnd => 0x3F,
Self::UnscheduledEventStart => 0x40,
Self::UnscheduledEventEnd => 0x41,
Self::AlternateContentOpportunityStart => 0x42,
Self::AlternateContentOpportunityEnd => 0x43,
Self::ProviderAdBlockStart => 0x44,
Self::ProviderAdBlockEnd => 0x45,
Self::DistributorAdBlockStart => 0x46,
Self::DistributorAdBlockEnd => 0x47,
Self::NetworkStart => 0x50,
Self::NetworkEnd => 0x51,
Self::Reserved(v) => v,
}
}
#[must_use]
pub fn has_sub_segments(self) -> bool {
matches!(
self.to_u8(),
0x30 | 0x32 | 0x34 | 0x36 | 0x38 | 0x3A | 0x44 | 0x46
)
}
}
impl SegmentationTypeId {
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::NotIndicated => "Not Indicated",
Self::ContentIdentification => "Content Identification",
Self::Private => "Private",
Self::ProgramStart => "Program Start",
Self::ProgramEnd => "Program End",
Self::ProgramEarlyTermination => "Program Early Termination",
Self::ProgramBreakaway => "Program Breakaway",
Self::ProgramResumption => "Program Resumption",
Self::ProgramRunoverPlanned => "Program Runover Planned",
Self::ProgramRunoverUnplanned => "Program Runover Unplanned",
Self::ProgramOverlapStart => "Program Overlap Start",
Self::ProgramBlackoutOverride => "Program Blackout Override",
Self::ProgramJoin => "Program Join",
Self::ProgramImmediateResumption => "Program Immediate Resumption",
Self::ChapterStart => "Chapter Start",
Self::ChapterEnd => "Chapter End",
Self::BreakStart => "Break Start",
Self::BreakEnd => "Break End",
Self::OpeningCreditStart => "Opening Credit Start",
Self::OpeningCreditEnd => "Opening Credit End",
Self::ClosingCreditStart => "Closing Credit Start",
Self::ClosingCreditEnd => "Closing Credit End",
Self::ProviderAdvertisementStart => "Provider Advertisement Start",
Self::ProviderAdvertisementEnd => "Provider Advertisement End",
Self::DistributorAdvertisementStart => "Distributor Advertisement Start",
Self::DistributorAdvertisementEnd => "Distributor Advertisement End",
Self::ProviderPlacementOpportunityStart => "Provider Placement Opportunity Start",
Self::ProviderPlacementOpportunityEnd => "Provider Placement Opportunity End",
Self::DistributorPlacementOpportunityStart => "Distributor Placement Opportunity Start",
Self::DistributorPlacementOpportunityEnd => "Distributor Placement Opportunity End",
Self::ProviderOverlayPlacementOpportunityStart => {
"Provider Overlay Placement Opportunity Start"
}
Self::ProviderOverlayPlacementOpportunityEnd => {
"Provider Overlay Placement Opportunity End"
}
Self::DistributorOverlayPlacementOpportunityStart => {
"Distributor Overlay Placement Opportunity Start"
}
Self::DistributorOverlayPlacementOpportunityEnd => {
"Distributor Overlay Placement Opportunity End"
}
Self::ProviderPromoStart => "Provider Promo Start",
Self::ProviderPromoEnd => "Provider Promo End",
Self::DistributorPromoStart => "Distributor Promo Start",
Self::DistributorPromoEnd => "Distributor Promo End",
Self::UnscheduledEventStart => "Unscheduled Event Start",
Self::UnscheduledEventEnd => "Unscheduled Event End",
Self::AlternateContentOpportunityStart => "Alternate Content Opportunity Start",
Self::AlternateContentOpportunityEnd => "Alternate Content Opportunity End",
Self::ProviderAdBlockStart => "Provider Ad Block Start",
Self::ProviderAdBlockEnd => "Provider Ad Block End",
Self::DistributorAdBlockStart => "Distributor Ad Block Start",
Self::DistributorAdBlockEnd => "Distributor Ad Block End",
Self::NetworkStart => "Network Start",
Self::NetworkEnd => "Network End",
Self::Reserved(_) => "reserved",
}
}
}
dvb_common::impl_spec_display!(SegmentationTypeId, Reserved);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn upid_type_round_trips_all_bytes() {
for v in 0u8..=255 {
assert_eq!(SegmentationUpidType::from_u8(v).to_u8(), v);
}
}
#[test]
fn type_id_round_trips_all_bytes() {
for v in 0u8..=255 {
assert_eq!(SegmentationTypeId::from_u8(v).to_u8(), v);
}
}
#[test]
fn device_restrictions_round_trips() {
for v in 0u8..=3 {
assert_eq!(DeviceRestrictions::from_bits(v).bits(), v);
}
}
#[test]
fn named_values_match_spec() {
assert_eq!(
SegmentationTypeId::ProviderPlacementOpportunityStart.to_u8(),
0x34
);
assert_eq!(SegmentationUpidType::Mpu.to_u8(), 0x0C);
assert!(SegmentationTypeId::ProviderPlacementOpportunityStart.has_sub_segments());
assert!(!SegmentationTypeId::ProgramStart.has_sub_segments());
for v in [0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x44, 0x46] {
assert!(SegmentationTypeId::from_u8(v).has_sub_segments());
}
}
}