From f5393cb2094d267c694a1d61d1f6a5d86b283c06 Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Tue, 13 Feb 2018 01:00:23 +0900 Subject: [PATCH] Add `media_segment` module --- src/lib.rs | 3 +- src/media_segment.rs | 107 +++++++++++++++++++++++++++++++++++++++++ src/tag.rs | 110 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 src/media_segment.rs diff --git a/src/lib.rs b/src/lib.rs index de79f47..e8fd53d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,12 +4,13 @@ extern crate trackable; // pub mod playlist; // pub mod media_playlist; // pub mod master_playlist; -// pub mod media_segment; pub use error::{Error, ErrorKind}; pub mod attribute; +pub mod media_segment; pub mod string; pub mod tag; +pub mod value; pub mod version; mod error; diff --git a/src/media_segment.rs b/src/media_segment.rs new file mode 100644 index 0000000..77c4c03 --- /dev/null +++ b/src/media_segment.rs @@ -0,0 +1,107 @@ +use std::fmt; +use std::iter; + +use {ErrorKind, Result}; +use tag::{ExtInf, ExtXByteRange, ExtXDateRange, ExtXDiscontinuity, ExtXKey, ExtXMap, + ExtXProgramDateTime, MediaSegmentTag}; + +#[derive(Debug, Clone)] +pub struct MediaSegmentBuilder { + uri: Option, + ext_inf: Option, + ext_x_byterange: Option, + ext_x_daterange: Option, + ext_x_discontinuity: Option, + ext_x_key: Option, + ext_x_map: Option, + ext_x_program_date_time: Option, +} +impl MediaSegmentBuilder { + pub fn new() -> Self { + MediaSegmentBuilder { + uri: None, + ext_inf: None, + ext_x_byterange: None, + ext_x_daterange: None, + ext_x_discontinuity: None, + ext_x_key: None, + ext_x_map: None, + ext_x_program_date_time: None, + } + } + pub fn uri(&mut self, uri: String) -> &mut Self { + self.uri = Some(uri); + self + } + pub fn tag>(&mut self, tag: T) -> &mut Self { + match tag.into() { + MediaSegmentTag::ExtInf(t) => self.ext_inf = Some(t), + MediaSegmentTag::ExtXByteRange(t) => self.ext_x_byterange = Some(t), + MediaSegmentTag::ExtXDateRange(t) => self.ext_x_daterange = Some(t), + MediaSegmentTag::ExtXDiscontinuity(t) => self.ext_x_discontinuity = Some(t), + MediaSegmentTag::ExtXKey(t) => self.ext_x_key = Some(t), + MediaSegmentTag::ExtXMap(t) => self.ext_x_map = Some(t), + MediaSegmentTag::ExtXProgramDateTime(t) => self.ext_x_program_date_time = Some(t), + } + self + } + pub fn finish(self) -> Result { + let uri = track_assert_some!(self.uri, ErrorKind::InvalidInput); + let ext_inf = track_assert_some!(self.ext_inf, ErrorKind::InvalidInput); + let tags = iter::empty() + .chain(self.ext_x_byterange.into_iter().map(From::from)) + .chain(self.ext_x_daterange.into_iter().map(From::from)) + .chain(self.ext_x_discontinuity.into_iter().map(From::from)) + .chain(self.ext_x_key.into_iter().map(From::from)) + .chain(self.ext_x_map.into_iter().map(From::from)) + .chain(self.ext_x_program_date_time.into_iter().map(From::from)) + .collect(); + Ok(MediaSegment { uri, ext_inf, tags }) + } +} + +#[derive(Debug, Clone)] +pub struct MediaSegment { + pub uri: String, // TODO + pub ext_inf: ExtInf, + pub tags: Vec, +} +impl fmt::Display for MediaSegment { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for tag in &self.tags { + writeln!(f, "{}", tag)?; + } + writeln!(f, "{}", self.ext_inf)?; + writeln!(f, "{}", self.uri)?; + Ok(()) + } +} +impl MediaSegment { + pub fn uri(&self) -> &str { + &self.uri + } + pub fn inf(&self) -> &ExtInf { + &self.ext_inf + } + pub fn byte_range(&self) -> Option<&ExtXByteRange> { + self.tags.iter().filter_map(|t| t.as_byte_range()).nth(0) + } + pub fn date_range(&self) -> Option<&ExtXDateRange> { + self.tags.iter().filter_map(|t| t.as_date_range()).nth(0) + } + pub fn discontinuity(&self) -> Option<&ExtXDiscontinuity> { + self.tags.iter().filter_map(|t| t.as_discontinuity()).nth(0) + } + pub fn key(&self) -> Option<&ExtXKey> { + self.tags.iter().filter_map(|t| t.as_key()).nth(0) + } + pub fn map(&self) -> Option<&ExtXMap> { + self.tags.iter().filter_map(|t| t.as_map()).nth(0) + } + pub fn program_date_time(&self) -> Option<&ExtXProgramDateTime> { + self.tags + .iter() + .filter_map(|t| t.as_program_date_time()) + .nth(0) + } +} diff --git a/src/tag.rs b/src/tag.rs index ca4ab64..1094b57 100644 --- a/src/tag.rs +++ b/src/tag.rs @@ -15,6 +15,116 @@ macro_rules! may_invalid { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum MediaSegmentTag { + ExtInf(ExtInf), + ExtXByteRange(ExtXByteRange), + ExtXDateRange(ExtXDateRange), + ExtXDiscontinuity(ExtXDiscontinuity), + ExtXKey(ExtXKey), + ExtXMap(ExtXMap), + ExtXProgramDateTime(ExtXProgramDateTime), +} +impl MediaSegmentTag { + pub fn as_inf(&self) -> Option<&ExtInf> { + if let MediaSegmentTag::ExtInf(ref t) = *self { + Some(t) + } else { + None + } + } + pub fn as_byte_range(&self) -> Option<&ExtXByteRange> { + if let MediaSegmentTag::ExtXByteRange(ref t) = *self { + Some(t) + } else { + None + } + } + pub fn as_date_range(&self) -> Option<&ExtXDateRange> { + if let MediaSegmentTag::ExtXDateRange(ref t) = *self { + Some(t) + } else { + None + } + } + pub fn as_discontinuity(&self) -> Option<&ExtXDiscontinuity> { + if let MediaSegmentTag::ExtXDiscontinuity(ref t) = *self { + Some(t) + } else { + None + } + } + pub fn as_key(&self) -> Option<&ExtXKey> { + if let MediaSegmentTag::ExtXKey(ref t) = *self { + Some(t) + } else { + None + } + } + pub fn as_map(&self) -> Option<&ExtXMap> { + if let MediaSegmentTag::ExtXMap(ref t) = *self { + Some(t) + } else { + None + } + } + pub fn as_program_date_time(&self) -> Option<&ExtXProgramDateTime> { + if let MediaSegmentTag::ExtXProgramDateTime(ref t) = *self { + Some(t) + } else { + None + } + } +} +impl fmt::Display for MediaSegmentTag { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + MediaSegmentTag::ExtInf(ref t) => t.fmt(f), + MediaSegmentTag::ExtXByteRange(ref t) => t.fmt(f), + MediaSegmentTag::ExtXDateRange(ref t) => t.fmt(f), + MediaSegmentTag::ExtXDiscontinuity(ref t) => t.fmt(f), + MediaSegmentTag::ExtXKey(ref t) => t.fmt(f), + MediaSegmentTag::ExtXMap(ref t) => t.fmt(f), + MediaSegmentTag::ExtXProgramDateTime(ref t) => t.fmt(f), + } + } +} +impl From for MediaSegmentTag { + fn from(f: ExtInf) -> Self { + MediaSegmentTag::ExtInf(f) + } +} +impl From for MediaSegmentTag { + fn from(f: ExtXByteRange) -> Self { + MediaSegmentTag::ExtXByteRange(f) + } +} +impl From for MediaSegmentTag { + fn from(f: ExtXDateRange) -> Self { + MediaSegmentTag::ExtXDateRange(f) + } +} +impl From for MediaSegmentTag { + fn from(f: ExtXDiscontinuity) -> Self { + MediaSegmentTag::ExtXDiscontinuity(f) + } +} +impl From for MediaSegmentTag { + fn from(f: ExtXKey) -> Self { + MediaSegmentTag::ExtXKey(f) + } +} +impl From for MediaSegmentTag { + fn from(f: ExtXMap) -> Self { + MediaSegmentTag::ExtXMap(f) + } +} +impl From for MediaSegmentTag { + fn from(f: ExtXProgramDateTime) -> Self { + MediaSegmentTag::ExtXProgramDateTime(f) + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum Tag { ExtM3u(ExtM3u),