1
0
Fork 0
mirror of https://github.com/sile/hls_m3u8.git synced 2024-06-26 08:20:32 +00:00
hls_m3u8/src/line.rs

199 lines
7.3 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 {
2019-10-03 15:01:15 +00:00
pub fn new() -> Self { Self::default() }
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> {
2019-10-05 14:08:03 +00:00
let mut result = Self::new();
2019-09-14 09:57:56 +00:00
2019-09-14 10:29:54 +00:00
let mut stream_inf = false;
let mut stream_inf_line = None;
for l in input.lines() {
2019-10-06 14:39:18 +00:00
let raw_line = l.trim();
2019-09-14 10:29:54 +00:00
2019-10-06 14:39:18 +00:00
if raw_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
2019-10-06 14:39:18 +00:00
let line = {
if raw_line.starts_with(tags::ExtXStreamInf::PREFIX) {
2019-09-14 10:29:54 +00:00
stream_inf = true;
2019-10-06 14:39:18 +00:00
stream_inf_line = Some(raw_line);
2019-09-14 10:29:54 +00:00
continue;
2019-10-06 14:39:18 +00:00
} else if raw_line.starts_with("#EXT") {
Line::Tag(raw_line.parse()?)
} else if raw_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 {
2019-10-06 14:39:18 +00:00
let res = Line::Tag(format!("{}\n{}", first_line, raw_line).parse()?);
2019-09-14 10:29:54 +00:00
stream_inf_line = None;
res
} else {
continue;
}
} else {
2019-10-06 14:39:18 +00:00
Line::Uri(raw_line.to_string())
2019-09-14 10:29:54 +00:00
}
2019-09-14 09:57:56 +00:00
}
};
2019-10-06 14:39:18 +00:00
result.push(line);
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 IntoIter = ::std::vec::IntoIter<Line>;
2019-10-03 15:01:15 +00:00
type Item = Line;
2019-09-13 14:06:52 +00:00
2019-10-03 15:01:15 +00:00
fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
2019-09-14 09:57:56 +00:00
}
impl Deref for Lines {
type Target = Vec<Line>;
2019-10-03 15:01:15 +00:00
fn deref(&self) -> &Self::Target { &self.0 }
2019-09-14 09:57:56 +00:00
}
impl DerefMut for Lines {
2019-10-03 15:01:15 +00:00
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
2018-02-11 06:10:52 +00:00
}
#[derive(Debug, Clone, PartialEq)]
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)]
#[derive(Debug, Clone, PartialEq)]
2018-02-14 15:50:57 +00:00
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 {
2019-10-05 14:08:03 +00:00
Self::ExtM3u(value) => value.fmt(f),
Self::ExtXVersion(value) => value.fmt(f),
Self::ExtInf(value) => value.fmt(f),
Self::ExtXByteRange(value) => value.fmt(f),
Self::ExtXDiscontinuity(value) => value.fmt(f),
Self::ExtXKey(value) => value.fmt(f),
Self::ExtXMap(value) => value.fmt(f),
Self::ExtXProgramDateTime(value) => value.fmt(f),
Self::ExtXDateRange(value) => value.fmt(f),
Self::ExtXTargetDuration(value) => value.fmt(f),
Self::ExtXMediaSequence(value) => value.fmt(f),
Self::ExtXDiscontinuitySequence(value) => value.fmt(f),
Self::ExtXEndList(value) => value.fmt(f),
Self::ExtXPlaylistType(value) => value.fmt(f),
Self::ExtXIFramesOnly(value) => value.fmt(f),
Self::ExtXMedia(value) => value.fmt(f),
Self::ExtXStreamInf(value) => value.fmt(f),
Self::ExtXIFrameStreamInf(value) => value.fmt(f),
Self::ExtXSessionData(value) => value.fmt(f),
Self::ExtXSessionKey(value) => value.fmt(f),
Self::ExtXIndependentSegments(value) => value.fmt(f),
Self::ExtXStart(value) => value.fmt(f),
Self::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
2019-10-03 14:23:27 +00:00
fn from_str(input: &str) -> Result<Self, Self::Err> {
if input.starts_with(tags::ExtM3u::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtM3u)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXVersion::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXVersion)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtInf::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtInf)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXByteRange::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXByteRange)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXDiscontinuity::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXDiscontinuity)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXKey::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXKey)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXMap::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXMap)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXProgramDateTime::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXProgramDateTime)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXTargetDuration::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXTargetDuration)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXDateRange::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXDateRange)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXMediaSequence::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXMediaSequence)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXDiscontinuitySequence::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXDiscontinuitySequence)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXEndList::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXEndList)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXPlaylistType::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXPlaylistType)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXIFramesOnly::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXIFramesOnly)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXMedia::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXMedia).map_err(Error::custom)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXStreamInf::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXStreamInf)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXIFrameStreamInf::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXIFrameStreamInf)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXSessionData::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXSessionData)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXSessionKey::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXSessionKey)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXIndependentSegments::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXIndependentSegments)
2019-10-03 14:23:27 +00:00
} else if input.starts_with(tags::ExtXStart::PREFIX) {
2019-10-05 14:08:03 +00:00
input.parse().map(Self::ExtXStart)
2018-02-14 15:50:57 +00:00
} else {
2019-10-05 14:08:03 +00:00
Ok(Self::Unknown(input.to_string()))
2018-02-14 15:50:57 +00:00
}
}
}