broadcast_dash/
descriptors.rs1use broadcast_common::impl_spec_display;
8
9use super::model::Descriptor;
10
11pub const SCHEME_ROLE: &str = "urn:mpeg:dash:role:2011";
13pub const SCHEME_PERIOD_CONTINUITY: &str = "urn:mpeg:dash:period-continuity:2015";
15pub const SCHEME_PERIOD_CONNECTIVITY: &str = "urn:mpeg:dash:period-connectivity:2015";
17pub const SCHEME_RESET: &str = "urn:mpeg:dash:reset:2016";
19pub const SCHEME_URLPARAM: &str = "urn:mpeg:dash:urlparam:2014";
21pub const SCHEME_URLPARAM_2016: &str = "urn:mpeg:dash:urlparam:2016";
24pub const SCHEME_LAST_SEGMENT_NUMBER: &str = "http://dashif.org/guidelines/last-segment-number";
26pub const XLINK_RESOLVE_TO_ZERO: &str = "urn:mpeg:dash:resolve-to-zero:2013";
28pub const SCHEME_MP4_PROTECTION: &str = "urn:mpeg:dash:mp4protection:2011";
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33#[non_exhaustive]
34pub enum Role {
35 Caption,
37 Subtitle,
39 Main,
41 Alternate,
43 Supplementary,
45 Commentary,
47 Dub,
49 Description,
51 Sign,
53 Metadata,
55 EnhancedAudioIntelligibility,
57 Emergency,
59 ForcedSubtitle,
61 EasyReader,
63 Karaoke,
65 Other,
67}
68
69impl Role {
70 #[must_use]
72 pub fn from_value(value: &str) -> Self {
73 match value {
74 "caption" => Self::Caption,
75 "subtitle" => Self::Subtitle,
76 "main" => Self::Main,
77 "alternate" => Self::Alternate,
78 "supplementary" => Self::Supplementary,
79 "commentary" => Self::Commentary,
80 "dub" => Self::Dub,
81 "description" => Self::Description,
82 "sign" => Self::Sign,
83 "metadata" => Self::Metadata,
84 "enhanced-audio-intelligibility" => Self::EnhancedAudioIntelligibility,
85 "emergency" => Self::Emergency,
86 "forced-subtitle" => Self::ForcedSubtitle,
87 "easyreader" => Self::EasyReader,
88 "karaoke" => Self::Karaoke,
89 _ => Self::Other,
90 }
91 }
92
93 #[must_use]
95 pub fn name(&self) -> &'static str {
96 match self {
97 Self::Caption => "caption",
98 Self::Subtitle => "subtitle",
99 Self::Main => "main",
100 Self::Alternate => "alternate",
101 Self::Supplementary => "supplementary",
102 Self::Commentary => "commentary",
103 Self::Dub => "dub",
104 Self::Description => "description",
105 Self::Sign => "sign",
106 Self::Metadata => "metadata",
107 Self::EnhancedAudioIntelligibility => "enhanced-audio-intelligibility",
108 Self::Emergency => "emergency",
109 Self::ForcedSubtitle => "forced-subtitle",
110 Self::EasyReader => "easyreader",
111 Self::Karaoke => "karaoke",
112 Self::Other => "other",
113 }
114 }
115}
116impl_spec_display!(Role);
117
118#[must_use]
120pub fn find<'a>(descriptors: &'a [Descriptor], scheme: &str) -> Option<&'a Descriptor> {
121 descriptors.iter().find(|d| d.scheme_id_uri == scheme)
122}
123
124pub const UNDERSTOOD_ESSENTIAL: &[&str] = &[
128 SCHEME_PERIOD_CONTINUITY,
129 SCHEME_PERIOD_CONNECTIVITY,
130 SCHEME_RESET,
131 SCHEME_URLPARAM,
132 SCHEME_LAST_SEGMENT_NUMBER,
133];
134
135#[must_use]
137pub fn essential_understood(descriptor: &Descriptor) -> bool {
138 UNDERSTOOD_ESSENTIAL.contains(&descriptor.scheme_id_uri.as_str())
139}
140
141#[cfg(test)]
142mod scheme_tests {
143 use super::*;
144
145 #[test]
146 fn scheme_constants_are_the_registered_uris() {
147 assert_eq!(SCHEME_URLPARAM_2016, "urn:mpeg:dash:urlparam:2016");
148 assert_eq!(SCHEME_MP4_PROTECTION, "urn:mpeg:dash:mp4protection:2011");
149 assert_ne!(SCHEME_URLPARAM_2016, SCHEME_URLPARAM);
150 }
151
152 #[test]
153 fn the_2016_urlparam_scheme_is_not_an_understood_essential_property() {
154 let d = Descriptor {
155 scheme_id_uri: SCHEME_URLPARAM_2016.into(),
156 ..Descriptor::default()
157 };
158 assert!(!essential_understood(&d));
159 let known = Descriptor {
160 scheme_id_uri: SCHEME_URLPARAM.into(),
161 ..Descriptor::default()
162 };
163 assert!(essential_understood(&known));
164 }
165}