diff --git a/src/lib.rs b/src/lib.rs index 45b1bc5..fc1726f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,12 @@ clippy::nursery, clippy::cargo )] -#![allow(clippy::multiple_crate_versions, clippy::must_use_candidate)] +#![allow( + clippy::multiple_crate_versions, + clippy::must_use_candidate, + clippy::module_name_repetitions, + clippy::default_trait_access +)] #![warn( missing_docs, missing_copy_implementations, diff --git a/src/line.rs b/src/line.rs index f36782a..51b0de3 100644 --- a/src/line.rs +++ b/src/line.rs @@ -1,93 +1,86 @@ use std::fmt; -use std::ops::{Deref, DerefMut}; use std::str::FromStr; use crate::tags; use crate::Error; -#[derive(Debug, Default)] -pub struct Lines(Vec); - -impl Lines { - pub fn new() -> Self { Self::default() } +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)] +pub(crate) struct Lines<'a> { + buffer: &'a str, + // the line at which the iterator currently is + position: usize, } -impl FromStr for Lines { - type Err = Error; - - fn from_str(input: &str) -> Result { - let mut result = Self::new(); +impl<'a> Iterator for Lines<'a> { + type Item = crate::Result; + fn next(&mut self) -> Option { let mut stream_inf = false; let mut stream_inf_line = None; - for l in input.lines() { - let raw_line = l.trim(); + for line in self.buffer.lines().skip(self.position) { + let line = line.trim(); + self.position += 1; - if raw_line.is_empty() { + if line.is_empty() { continue; } - let line = { - if raw_line.starts_with(tags::ExtXStreamInf::PREFIX) { - stream_inf = true; - stream_inf_line = Some(raw_line); + if line.starts_with(tags::ExtXStreamInf::PREFIX) { + stream_inf = true; + stream_inf_line = Some(line); - continue; - } else if raw_line.starts_with("#EXT") { - Line::Tag(raw_line.parse()?) - } else if raw_line.starts_with('#') { - continue; // ignore comments - } else { - // stream inf line needs special treatment - if stream_inf { - stream_inf = false; - if let Some(first_line) = stream_inf_line { - let res = Line::Tag(format!("{}\n{}", first_line, raw_line).parse()?); - stream_inf_line = None; - res - } else { - continue; + continue; + } else if line.starts_with("#EXT") { + match line.parse() { + Ok(value) => return Some(Ok(Line::Tag(value))), + Err(e) => return Some(Err(e)), + } + } else if line.starts_with('#') { + continue; // ignore comments + } else { + // stream inf line needs special treatment + if stream_inf { + stream_inf = false; + + if let Some(first_line) = stream_inf_line { + match format!("{}\n{}", first_line, line).parse() { + Ok(value) => { + return Some(Ok(Line::Tag(value))); + } + Err(e) => return Some(Err(e)), } } else { - Line::Uri(raw_line.to_string()) + continue; } + } else { + return Some(Ok(Line::Uri(line.to_string()))); } - }; - - result.push(line); + } } - Ok(result) + None } } -impl IntoIterator for Lines { - type IntoIter = ::std::vec::IntoIter; - type Item = Line; - - fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } -} - -impl Deref for Lines { - type Target = Vec; - - fn deref(&self) -> &Self::Target { &self.0 } -} - -impl DerefMut for Lines { - fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } +impl<'a> From<&'a str> for Lines<'a> { + fn from(buffer: &'a str) -> Self { + Self { + buffer, + position: 0, + } + } } #[derive(Debug, Clone, PartialEq)] -pub enum Line { +pub(crate) enum Line { Tag(Tag), Uri(String), } #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq)] -pub enum Tag { +pub(crate) enum Tag { ExtM3u(tags::ExtM3u), ExtXVersion(tags::ExtXVersion), ExtInf(tags::ExtInf), diff --git a/src/master_playlist.rs b/src/master_playlist.rs index ce56b7c..d21ef1a 100644 --- a/src/master_playlist.rs +++ b/src/master_playlist.rs @@ -272,8 +272,8 @@ impl FromStr for MasterPlaylist { let mut session_key_tags = vec![]; let mut unknown_tags = vec![]; - for (i, line) in input.parse::()?.into_iter().enumerate() { - match line { + for (i, line) in Lines::from(input).enumerate() { + match line? { Line::Tag(tag) => { if i == 0 { if tag != Tag::ExtM3u(ExtM3u) { diff --git a/src/media_playlist.rs b/src/media_playlist.rs index 680d6c5..cf8b05d 100644 --- a/src/media_playlist.rs +++ b/src/media_playlist.rs @@ -285,8 +285,8 @@ fn parse_media_playlist( let mut available_key_tags: Vec = vec![]; - for (i, line) in input.parse::()?.into_iter().enumerate() { - match line { + for (i, line) in Lines::from(input).enumerate() { + match line? { Line::Tag(tag) => { if i == 0 { if tag != Tag::ExtM3u(ExtM3u) { diff --git a/src/media_segment.rs b/src/media_segment.rs index 803086d..ec7889c 100644 --- a/src/media_segment.rs +++ b/src/media_segment.rs @@ -14,7 +14,7 @@ use crate::{Encrypted, RequiredVersion}; #[builder(setter(into, strip_option))] #[shorthand(enable(must_use, get_mut, collection_magic))] pub struct MediaSegment { - /// Sets all [`ExtXKey`] tags. + /// All [`ExtXKey`] tags. #[builder(default)] keys: Vec, /// The [`ExtXMap`] tag associated with the media segment.