1
0
Fork 0
mirror of https://github.com/sile/hls_m3u8.git synced 2024-05-21 01:38:07 +00:00
hls_m3u8/src/line.rs

207 lines
7.1 KiB
Rust
Raw Normal View History

2018-02-14 15:50:57 +00:00
use std::fmt;
2019-09-14 09:57:56 +00:00
use std::ops::{Deref, DerefMut};
2018-02-14 15:50:57 +00:00
use std::str::FromStr;
2019-09-13 14:06:52 +00:00
use crate::tags;
use crate::Error;
2019-09-14 09:57:56 +00:00
#[derive(Debug, Default)]
pub struct Lines(Vec<Line>);
impl Lines {
pub fn new() -> Self {
Self::default()
2018-02-11 06:10:52 +00:00
}
2019-09-14 09:57:56 +00:00
}
2018-02-11 06:10:52 +00:00
2019-09-14 09:57:56 +00:00
impl FromStr for Lines {
type Err = Error;
fn from_str(input: &str) -> Result<Self, Self::Err> {
let mut result = Lines::new();
2019-09-14 10:29:54 +00:00
let mut stream_inf = false;
let mut stream_inf_line = None;
for l in input.lines() {
let line = l.trim();
2019-09-22 18:33:40 +00:00
if line.is_empty() {
2019-09-14 09:57:56 +00:00
continue;
2018-02-11 06:10:52 +00:00
}
2019-09-14 09:57:56 +00:00
let pline = {
2019-09-14 10:29:54 +00:00
if line.starts_with(tags::ExtXStreamInf::PREFIX) {
stream_inf = true;
stream_inf_line = Some(line);
continue;
} else if line.starts_with("#EXT") {
2019-09-14 09:57:56 +00:00
Line::Tag(line.parse()?)
2019-09-22 18:33:40 +00:00
} else if line.starts_with('#') {
2019-09-14 09:57:56 +00:00
continue; // ignore comments
} else {
2019-09-15 08:40:45 +00:00
// stream inf line needs special treatment
2019-09-14 10:29:54 +00:00
if stream_inf {
stream_inf = false;
if let Some(first_line) = stream_inf_line {
let res = Line::Tag(format!("{}\n{}", first_line, line).parse()?);
stream_inf_line = None;
res
} else {
continue;
}
} else {
2019-09-21 10:11:36 +00:00
Line::Uri(line.trim().to_string())
2019-09-14 10:29:54 +00:00
}
2019-09-14 09:57:56 +00:00
}
};
result.push(pline);
2018-02-11 06:10:52 +00:00
}
2019-09-14 09:57:56 +00:00
Ok(result)
2018-02-11 06:10:52 +00:00
}
}
2019-09-13 14:06:52 +00:00
2019-09-14 09:57:56 +00:00
impl IntoIterator for Lines {
type Item = Line;
type IntoIter = ::std::vec::IntoIter<Line>;
2019-09-13 14:06:52 +00:00
2019-09-14 09:57:56 +00:00
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl Deref for Lines {
type Target = Vec<Line>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Lines {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
2018-02-11 06:10:52 +00:00
}
}
#[derive(Debug, PartialEq, Eq)]
2019-09-14 09:57:56 +00:00
pub enum Line {
2018-02-11 06:10:52 +00:00
Tag(Tag),
2019-09-21 10:11:36 +00:00
Uri(String),
2018-02-11 06:10:52 +00:00
}
2019-03-31 10:00:02 +00:00
#[allow(clippy::large_enum_variant)]
2018-02-14 15:50:57 +00:00
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Tag {
2018-02-14 19:51:44 +00:00
ExtM3u(tags::ExtM3u),
ExtXVersion(tags::ExtXVersion),
ExtInf(tags::ExtInf),
ExtXByteRange(tags::ExtXByteRange),
ExtXDiscontinuity(tags::ExtXDiscontinuity),
ExtXKey(tags::ExtXKey),
ExtXMap(tags::ExtXMap),
ExtXProgramDateTime(tags::ExtXProgramDateTime),
ExtXDateRange(tags::ExtXDateRange),
ExtXTargetDuration(tags::ExtXTargetDuration),
ExtXMediaSequence(tags::ExtXMediaSequence),
ExtXDiscontinuitySequence(tags::ExtXDiscontinuitySequence),
ExtXEndList(tags::ExtXEndList),
ExtXPlaylistType(tags::ExtXPlaylistType),
ExtXIFramesOnly(tags::ExtXIFramesOnly),
ExtXMedia(tags::ExtXMedia),
ExtXStreamInf(tags::ExtXStreamInf),
ExtXIFrameStreamInf(tags::ExtXIFrameStreamInf),
ExtXSessionData(tags::ExtXSessionData),
ExtXSessionKey(tags::ExtXSessionKey),
ExtXIndependentSegments(tags::ExtXIndependentSegments),
ExtXStart(tags::ExtXStart),
2019-09-15 09:05:22 +00:00
Unknown(String),
2018-02-14 15:50:57 +00:00
}
2019-09-13 14:06:52 +00:00
2018-02-14 15:50:57 +00:00
impl fmt::Display for Tag {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2019-09-14 19:42:06 +00:00
match &self {
Tag::ExtM3u(value) => value.fmt(f),
Tag::ExtXVersion(value) => value.fmt(f),
Tag::ExtInf(value) => value.fmt(f),
Tag::ExtXByteRange(value) => value.fmt(f),
Tag::ExtXDiscontinuity(value) => value.fmt(f),
Tag::ExtXKey(value) => value.fmt(f),
Tag::ExtXMap(value) => value.fmt(f),
Tag::ExtXProgramDateTime(value) => value.fmt(f),
Tag::ExtXDateRange(value) => value.fmt(f),
Tag::ExtXTargetDuration(value) => value.fmt(f),
Tag::ExtXMediaSequence(value) => value.fmt(f),
Tag::ExtXDiscontinuitySequence(value) => value.fmt(f),
Tag::ExtXEndList(value) => value.fmt(f),
Tag::ExtXPlaylistType(value) => value.fmt(f),
Tag::ExtXIFramesOnly(value) => value.fmt(f),
Tag::ExtXMedia(value) => value.fmt(f),
Tag::ExtXStreamInf(value) => value.fmt(f),
Tag::ExtXIFrameStreamInf(value) => value.fmt(f),
Tag::ExtXSessionData(value) => value.fmt(f),
Tag::ExtXSessionKey(value) => value.fmt(f),
Tag::ExtXIndependentSegments(value) => value.fmt(f),
Tag::ExtXStart(value) => value.fmt(f),
Tag::Unknown(value) => value.fmt(f),
2018-02-14 15:50:57 +00:00
}
}
}
2019-09-13 14:06:52 +00:00
2018-02-14 15:50:57 +00:00
impl FromStr for Tag {
type Err = Error;
2019-09-13 14:06:52 +00:00
fn from_str(s: &str) -> Result<Self, Self::Err> {
2018-02-14 19:51:44 +00:00
if s.starts_with(tags::ExtM3u::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtM3u)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXVersion::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXVersion)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtInf::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtInf)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXByteRange::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXByteRange)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXDiscontinuity::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXDiscontinuity)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXKey::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXKey)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXMap::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXMap)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXProgramDateTime::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXProgramDateTime)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXTargetDuration::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXTargetDuration)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXDateRange::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXDateRange)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXMediaSequence::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXMediaSequence)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXDiscontinuitySequence::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXDiscontinuitySequence)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXEndList::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXEndList)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXPlaylistType::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXPlaylistType)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXIFramesOnly::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXIFramesOnly)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXMedia::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXMedia)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXStreamInf::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXStreamInf)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXIFrameStreamInf::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXIFrameStreamInf)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXSessionData::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXSessionData)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXSessionKey::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXSessionKey)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXIndependentSegments::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXIndependentSegments)
2018-02-14 19:51:44 +00:00
} else if s.starts_with(tags::ExtXStart::PREFIX) {
2019-09-14 10:29:54 +00:00
s.parse().map(Tag::ExtXStart)
2018-02-14 15:50:57 +00:00
} else {
2019-09-15 09:05:22 +00:00
Ok(Tag::Unknown(s.to_string()))
2018-02-14 15:50:57 +00:00
}
}
}