mirror of
https://github.com/sile/hls_m3u8.git
synced 2024-12-23 12:30:29 +00:00
Refactor line
module
This commit is contained in:
parent
32b262713e
commit
0fdcf41732
6 changed files with 146 additions and 163 deletions
161
src/line.rs
161
src/line.rs
|
@ -1,19 +1,10 @@
|
|||
use {ErrorKind, Result};
|
||||
use tag::Tag;
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use {Error, ErrorKind, Result};
|
||||
use tag;
|
||||
use types::SingleLineString;
|
||||
|
||||
// [rfc8216#section-4.1]
|
||||
// > Playlist files MUST be encoded in UTF-8 [RFC3629]. They MUST NOT
|
||||
// > contain any Byte Order Mark (BOM); clients SHOULD fail to parse
|
||||
// > Playlists that contain a BOM or do not parse as UTF-8. Playlist
|
||||
// > files MUST NOT contain UTF-8 control characters (U+0000 to U+001F and
|
||||
// > U+007F to U+009F), with the exceptions of CR (U+000D) and LF
|
||||
// > (U+000A). All character sequences MUST be normalized according to
|
||||
// > Unicode normalization form "NFC" [UNICODE]. Note that US-ASCII
|
||||
// > [US_ASCII] conforms to these rules.
|
||||
// >
|
||||
// > Lines in a Playlist file are terminated by either a single line feed
|
||||
// > character or a carriage return character followed by a line feed
|
||||
// > character.
|
||||
#[derive(Debug)]
|
||||
pub struct Lines<'a> {
|
||||
input: &'a str,
|
||||
|
@ -27,9 +18,17 @@ impl<'a> Lines<'a> {
|
|||
let mut end = self.input.len();
|
||||
let mut next_start = self.input.len();
|
||||
let mut adjust = 0;
|
||||
let mut next_line_of_ext_x_stream_inf = false;
|
||||
for (i, c) in self.input.char_indices() {
|
||||
match c {
|
||||
'\n' => {
|
||||
if !next_line_of_ext_x_stream_inf
|
||||
&& self.input.starts_with(tag::ExtXStreamInf::PREFIX)
|
||||
{
|
||||
next_line_of_ext_x_stream_inf = true;
|
||||
adjust = 0;
|
||||
continue;
|
||||
}
|
||||
next_start = i + 1;
|
||||
end = i - adjust;
|
||||
break;
|
||||
|
@ -37,10 +36,8 @@ impl<'a> Lines<'a> {
|
|||
'\r' => {
|
||||
adjust = 1;
|
||||
}
|
||||
'\u{00}'...'\u{1F}' | '\u{7F}'...'\u{9f}' => {
|
||||
track_panic!(ErrorKind::InvalidInput);
|
||||
}
|
||||
_ => {
|
||||
track_assert!(!c.is_control(), ErrorKind::InvalidInput);
|
||||
adjust = 0;
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +50,8 @@ impl<'a> Lines<'a> {
|
|||
} else if raw_line.starts_with("#") {
|
||||
Line::Comment(raw_line)
|
||||
} else {
|
||||
Line::Uri(raw_line)
|
||||
let uri = track!(SingleLineString::new(raw_line))?;
|
||||
Line::Uri(uri)
|
||||
};
|
||||
self.input = &self.input[next_start..];
|
||||
Ok(line)
|
||||
|
@ -77,22 +75,113 @@ pub enum Line<'a> {
|
|||
Blank,
|
||||
Comment(&'a str),
|
||||
Tag(Tag),
|
||||
|
||||
// TODO:
|
||||
Uri(&'a str),
|
||||
Uri(SingleLineString),
|
||||
}
|
||||
|
||||
// TODO
|
||||
// #[cfg(test)]
|
||||
// mod test {
|
||||
// use super::*;
|
||||
|
||||
// #[test]
|
||||
// fn it_works() {
|
||||
// let mut lines = Lines::new("foo\nbar\r\nbaz");
|
||||
// assert_eq!(lines.next().and_then(|x| x.ok()), Some("foo"));
|
||||
// assert_eq!(lines.next().and_then(|x| x.ok()), Some("bar"));
|
||||
// assert_eq!(lines.next().and_then(|x| x.ok()), Some("baz"));
|
||||
// assert_eq!(lines.next().and_then(|x| x.ok()), None);
|
||||
// }
|
||||
// }
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Tag {
|
||||
ExtM3u(tag::ExtM3u),
|
||||
ExtXVersion(tag::ExtXVersion),
|
||||
ExtInf(tag::ExtInf),
|
||||
ExtXByteRange(tag::ExtXByteRange),
|
||||
ExtXDiscontinuity(tag::ExtXDiscontinuity),
|
||||
ExtXKey(tag::ExtXKey),
|
||||
ExtXMap(tag::ExtXMap),
|
||||
ExtXProgramDateTime(tag::ExtXProgramDateTime),
|
||||
ExtXDateRange(tag::ExtXDateRange),
|
||||
ExtXTargetDuration(tag::ExtXTargetDuration),
|
||||
ExtXMediaSequence(tag::ExtXMediaSequence),
|
||||
ExtXDiscontinuitySequence(tag::ExtXDiscontinuitySequence),
|
||||
ExtXEndList(tag::ExtXEndList),
|
||||
ExtXPlaylistType(tag::ExtXPlaylistType),
|
||||
ExtXIFramesOnly(tag::ExtXIFramesOnly),
|
||||
ExtXMedia(tag::ExtXMedia),
|
||||
ExtXStreamInf(tag::ExtXStreamInf),
|
||||
ExtXIFrameStreamInf(tag::ExtXIFrameStreamInf),
|
||||
ExtXSessionData(tag::ExtXSessionData),
|
||||
ExtXSessionKey(tag::ExtXSessionKey),
|
||||
ExtXIndependentSegments(tag::ExtXIndependentSegments),
|
||||
ExtXStart(tag::ExtXStart),
|
||||
Unknown(SingleLineString),
|
||||
}
|
||||
impl fmt::Display for Tag {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Tag::ExtM3u(ref t) => t.fmt(f),
|
||||
Tag::ExtXVersion(ref t) => t.fmt(f),
|
||||
Tag::ExtInf(ref t) => t.fmt(f),
|
||||
Tag::ExtXByteRange(ref t) => t.fmt(f),
|
||||
Tag::ExtXDiscontinuity(ref t) => t.fmt(f),
|
||||
Tag::ExtXKey(ref t) => t.fmt(f),
|
||||
Tag::ExtXMap(ref t) => t.fmt(f),
|
||||
Tag::ExtXProgramDateTime(ref t) => t.fmt(f),
|
||||
Tag::ExtXDateRange(ref t) => t.fmt(f),
|
||||
Tag::ExtXTargetDuration(ref t) => t.fmt(f),
|
||||
Tag::ExtXMediaSequence(ref t) => t.fmt(f),
|
||||
Tag::ExtXDiscontinuitySequence(ref t) => t.fmt(f),
|
||||
Tag::ExtXEndList(ref t) => t.fmt(f),
|
||||
Tag::ExtXPlaylistType(ref t) => t.fmt(f),
|
||||
Tag::ExtXIFramesOnly(ref t) => t.fmt(f),
|
||||
Tag::ExtXMedia(ref t) => t.fmt(f),
|
||||
Tag::ExtXStreamInf(ref t) => t.fmt(f),
|
||||
Tag::ExtXIFrameStreamInf(ref t) => t.fmt(f),
|
||||
Tag::ExtXSessionData(ref t) => t.fmt(f),
|
||||
Tag::ExtXSessionKey(ref t) => t.fmt(f),
|
||||
Tag::ExtXIndependentSegments(ref t) => t.fmt(f),
|
||||
Tag::ExtXStart(ref t) => t.fmt(f),
|
||||
Tag::Unknown(ref t) => t.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl FromStr for Tag {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
if s.starts_with(tag::ExtM3u::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtM3u))
|
||||
} else if s.starts_with(tag::ExtXVersion::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXVersion))
|
||||
} else if s.starts_with(tag::ExtInf::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtInf))
|
||||
} else if s.starts_with(tag::ExtXByteRange::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXByteRange))
|
||||
} else if s.starts_with(tag::ExtXDiscontinuity::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXDiscontinuity))
|
||||
} else if s.starts_with(tag::ExtXKey::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXKey))
|
||||
} else if s.starts_with(tag::ExtXMap::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXMap))
|
||||
} else if s.starts_with(tag::ExtXProgramDateTime::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXProgramDateTime))
|
||||
} else if s.starts_with(tag::ExtXTargetDuration::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXTargetDuration))
|
||||
} else if s.starts_with(tag::ExtXDateRange::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXDateRange))
|
||||
} else if s.starts_with(tag::ExtXMediaSequence::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXMediaSequence))
|
||||
} else if s.starts_with(tag::ExtXDiscontinuitySequence::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXDiscontinuitySequence))
|
||||
} else if s.starts_with(tag::ExtXEndList::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXEndList))
|
||||
} else if s.starts_with(tag::ExtXPlaylistType::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXPlaylistType))
|
||||
} else if s.starts_with(tag::ExtXIFramesOnly::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXIFramesOnly))
|
||||
} else if s.starts_with(tag::ExtXMedia::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXMedia))
|
||||
} else if s.starts_with(tag::ExtXStreamInf::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXStreamInf))
|
||||
} else if s.starts_with(tag::ExtXIFrameStreamInf::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXIFrameStreamInf))
|
||||
} else if s.starts_with(tag::ExtXSessionData::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXSessionData))
|
||||
} else if s.starts_with(tag::ExtXSessionKey::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXSessionKey))
|
||||
} else if s.starts_with(tag::ExtXIndependentSegments::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXIndependentSegments))
|
||||
} else if s.starts_with(tag::ExtXStart::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXStart))
|
||||
} else {
|
||||
track!(SingleLineString::new(s)).map(Tag::Unknown)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ use std::fmt;
|
|||
use std::str::FromStr;
|
||||
|
||||
use {Error, ErrorKind, Result};
|
||||
use line::{Line, Lines};
|
||||
use line::{Line, Lines, Tag};
|
||||
use tag::{ExtM3u, ExtXIFrameStreamInf, ExtXIndependentSegments, ExtXMedia, ExtXSessionData,
|
||||
ExtXSessionKey, ExtXStart, ExtXStreamInf, ExtXVersion, Tag};
|
||||
ExtXSessionKey, ExtXStart, ExtXStreamInf, ExtXVersion};
|
||||
use types::ProtocolVersion;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -132,16 +132,14 @@ impl FromStr for MasterPlaylist {
|
|||
track_assert_eq!(start, None, ErrorKind::InvalidInput);
|
||||
start = Some(t);
|
||||
}
|
||||
Tag::Unknown(_) => {
|
||||
// [6.3.1. General Client Responsibilities]
|
||||
// > ignore any unrecognized tags.
|
||||
}
|
||||
}
|
||||
}
|
||||
Line::Uri(uri) => {
|
||||
let (line, inf) = track_assert_some!(last_stream_inf, ErrorKind::InvalidInput);
|
||||
track_assert_eq!(line + 1, i, ErrorKind::InvalidInput);
|
||||
stream_infs.push(ExtXStreamInfWithUri {
|
||||
inf,
|
||||
uri: uri.to_owned(),
|
||||
});
|
||||
last_stream_inf = None;
|
||||
track_panic!(ErrorKind::InvalidInput, "Unexpected URI: {:?}", uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ use std::fmt;
|
|||
use std::str::FromStr;
|
||||
|
||||
use {Error, ErrorKind, Result};
|
||||
use line::{Line, Lines};
|
||||
use line::{Line, Lines, Tag};
|
||||
use media_segment::{MediaSegment, MediaSegmentBuilder};
|
||||
use tag::{ExtM3u, ExtXDiscontinuitySequence, ExtXEndList, ExtXIFramesOnly,
|
||||
ExtXIndependentSegments, ExtXMediaSequence, ExtXPlaylistType, ExtXStart,
|
||||
ExtXTargetDuration, ExtXVersion, Tag};
|
||||
ExtXTargetDuration, ExtXVersion};
|
||||
use types::ProtocolVersion;
|
||||
|
||||
// TODO: There MUST NOT be more than one Media Playlist tag of each type in any Media Playlist.
|
||||
|
@ -167,10 +167,14 @@ impl FromStr for MediaPlaylist {
|
|||
track_assert_eq!(start, None, ErrorKind::InvalidInput);
|
||||
start = Some(t);
|
||||
}
|
||||
Tag::Unknown(_) => {
|
||||
// [6.3.1. General Client Responsibilities]
|
||||
// > ignore any unrecognized tags.
|
||||
}
|
||||
}
|
||||
}
|
||||
Line::Uri(uri) => {
|
||||
segment.uri(uri.to_owned());
|
||||
segment.uri(uri);
|
||||
segments.push(track!(segment.finish())?);
|
||||
segment = MediaSegmentBuilder::new();
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ use std::iter;
|
|||
use {ErrorKind, Result};
|
||||
use tag::{ExtInf, ExtXByteRange, ExtXDateRange, ExtXDiscontinuity, ExtXKey, ExtXMap,
|
||||
ExtXProgramDateTime, MediaSegmentTag};
|
||||
use types::SingleLineString;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MediaSegmentBuilder {
|
||||
uri: Option<String>,
|
||||
uri: Option<SingleLineString>,
|
||||
ext_inf: Option<ExtInf>,
|
||||
ext_x_byterange: Option<ExtXByteRange>,
|
||||
ext_x_daterange: Option<ExtXDateRange>,
|
||||
|
@ -29,7 +30,7 @@ impl MediaSegmentBuilder {
|
|||
ext_x_program_date_time: None,
|
||||
}
|
||||
}
|
||||
pub fn uri(&mut self, uri: String) -> &mut Self {
|
||||
pub fn uri(&mut self, uri: SingleLineString) -> &mut Self {
|
||||
self.uri = Some(uri);
|
||||
self
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ impl MediaSegmentBuilder {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MediaSegment {
|
||||
pub uri: String, // TODO
|
||||
pub uri: SingleLineString,
|
||||
pub ext_inf: ExtInf,
|
||||
pub tags: Vec<MediaSegmentTag>,
|
||||
}
|
||||
|
|
|
@ -368,8 +368,8 @@ impl fmt::Display for ExtXStreamInf {
|
|||
impl FromStr for ExtXStreamInf {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
let mut lines = s.splitn(2, '\n'); // TODO:
|
||||
let first_line = lines.next().expect("Never fails");
|
||||
let mut lines = s.splitn(2, '\n');
|
||||
let first_line = lines.next().expect("Never fails").trim_right_matches('\r');
|
||||
let second_line = track_assert_some!(lines.next(), ErrorKind::InvalidInput);
|
||||
|
||||
track_assert!(
|
||||
|
|
111
src/tag/mod.rs
111
src/tag/mod.rs
|
@ -2,10 +2,9 @@
|
|||
//!
|
||||
//! [4.3. Playlist Tags]: https://tools.ietf.org/html/rfc8216#section-4.3
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use trackable::error::ErrorKindExt;
|
||||
|
||||
use {Error, ErrorKind, Result};
|
||||
use {ErrorKind, Result};
|
||||
|
||||
macro_rules! may_invalid {
|
||||
($expr:expr) => {
|
||||
|
@ -123,114 +122,6 @@ impl_from!(MediaSegmentTag, ExtXKey);
|
|||
impl_from!(MediaSegmentTag, ExtXMap);
|
||||
impl_from!(MediaSegmentTag, ExtXProgramDateTime);
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Tag {
|
||||
ExtM3u(ExtM3u),
|
||||
ExtXVersion(ExtXVersion),
|
||||
ExtInf(ExtInf),
|
||||
ExtXByteRange(ExtXByteRange),
|
||||
ExtXDiscontinuity(ExtXDiscontinuity),
|
||||
ExtXKey(ExtXKey),
|
||||
ExtXMap(ExtXMap),
|
||||
ExtXProgramDateTime(ExtXProgramDateTime),
|
||||
ExtXDateRange(ExtXDateRange),
|
||||
ExtXTargetDuration(ExtXTargetDuration),
|
||||
ExtXMediaSequence(ExtXMediaSequence),
|
||||
ExtXDiscontinuitySequence(ExtXDiscontinuitySequence),
|
||||
ExtXEndList(ExtXEndList),
|
||||
ExtXPlaylistType(ExtXPlaylistType),
|
||||
ExtXIFramesOnly(ExtXIFramesOnly),
|
||||
ExtXMedia(ExtXMedia),
|
||||
ExtXStreamInf(ExtXStreamInf),
|
||||
ExtXIFrameStreamInf(ExtXIFrameStreamInf),
|
||||
ExtXSessionData(ExtXSessionData),
|
||||
ExtXSessionKey(ExtXSessionKey),
|
||||
ExtXIndependentSegments(ExtXIndependentSegments),
|
||||
ExtXStart(ExtXStart),
|
||||
}
|
||||
impl fmt::Display for Tag {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Tag::ExtM3u(ref t) => t.fmt(f),
|
||||
Tag::ExtXVersion(ref t) => t.fmt(f),
|
||||
Tag::ExtInf(ref t) => t.fmt(f),
|
||||
Tag::ExtXByteRange(ref t) => t.fmt(f),
|
||||
Tag::ExtXDiscontinuity(ref t) => t.fmt(f),
|
||||
Tag::ExtXKey(ref t) => t.fmt(f),
|
||||
Tag::ExtXMap(ref t) => t.fmt(f),
|
||||
Tag::ExtXProgramDateTime(ref t) => t.fmt(f),
|
||||
Tag::ExtXDateRange(ref t) => t.fmt(f),
|
||||
Tag::ExtXTargetDuration(ref t) => t.fmt(f),
|
||||
Tag::ExtXMediaSequence(ref t) => t.fmt(f),
|
||||
Tag::ExtXDiscontinuitySequence(ref t) => t.fmt(f),
|
||||
Tag::ExtXEndList(ref t) => t.fmt(f),
|
||||
Tag::ExtXPlaylistType(ref t) => t.fmt(f),
|
||||
Tag::ExtXIFramesOnly(ref t) => t.fmt(f),
|
||||
Tag::ExtXMedia(ref t) => t.fmt(f),
|
||||
Tag::ExtXStreamInf(ref t) => t.fmt(f),
|
||||
Tag::ExtXIFrameStreamInf(ref t) => t.fmt(f),
|
||||
Tag::ExtXSessionData(ref t) => t.fmt(f),
|
||||
Tag::ExtXSessionKey(ref t) => t.fmt(f),
|
||||
Tag::ExtXIndependentSegments(ref t) => t.fmt(f),
|
||||
Tag::ExtXStart(ref t) => t.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl FromStr for Tag {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
if s.starts_with(ExtM3u::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtM3u))
|
||||
} else if s.starts_with(ExtXVersion::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXVersion))
|
||||
} else if s.starts_with(ExtInf::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtInf))
|
||||
} else if s.starts_with(ExtXByteRange::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXByteRange))
|
||||
} else if s.starts_with(ExtXDiscontinuity::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXDiscontinuity))
|
||||
} else if s.starts_with(ExtXKey::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXKey))
|
||||
} else if s.starts_with(ExtXMap::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXMap))
|
||||
} else if s.starts_with(ExtXProgramDateTime::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXProgramDateTime))
|
||||
} else if s.starts_with(ExtXTargetDuration::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXTargetDuration))
|
||||
} else if s.starts_with(ExtXDateRange::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXDateRange))
|
||||
} else if s.starts_with(ExtXMediaSequence::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXMediaSequence))
|
||||
} else if s.starts_with(ExtXDiscontinuitySequence::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXDiscontinuitySequence))
|
||||
} else if s.starts_with(ExtXEndList::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXEndList))
|
||||
} else if s.starts_with(ExtXPlaylistType::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXPlaylistType))
|
||||
} else if s.starts_with(ExtXIFramesOnly::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXIFramesOnly))
|
||||
} else if s.starts_with(ExtXMedia::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXMedia))
|
||||
} else if s.starts_with(ExtXStreamInf::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXStreamInf))
|
||||
} else if s.starts_with(ExtXIFrameStreamInf::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXIFrameStreamInf))
|
||||
} else if s.starts_with(ExtXSessionData::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXSessionData))
|
||||
} else if s.starts_with(ExtXSessionKey::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXSessionKey))
|
||||
} else if s.starts_with(ExtXIndependentSegments::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXIndependentSegments))
|
||||
} else if s.starts_with(ExtXStart::PREFIX) {
|
||||
track!(s.parse().map(Tag::ExtXStart))
|
||||
} else {
|
||||
// TODO: ignore any unrecognized tags. (section-6.3.1)
|
||||
track_panic!(ErrorKind::InvalidInput, "Unknown tag: {:?}", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_yes_or_no(s: &str) -> Result<bool> {
|
||||
match s {
|
||||
"YES" => Ok(true),
|
||||
|
|
Loading…
Reference in a new issue