mirror of
https://github.com/sile/hls_m3u8.git
synced 2024-11-25 16:41:00 +00:00
rewrite Lines
to reduce allocations
This commit is contained in:
parent
006f36ff47
commit
e6a1103d24
5 changed files with 59 additions and 61 deletions
|
@ -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,
|
||||
|
|
83
src/line.rs
83
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<Line>);
|
||||
|
||||
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<Self, Self::Err> {
|
||||
let mut result = Self::new();
|
||||
impl<'a> Iterator for Lines<'a> {
|
||||
type Item = crate::Result<Line>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
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) {
|
||||
if line.starts_with(tags::ExtXStreamInf::PREFIX) {
|
||||
stream_inf = true;
|
||||
stream_inf_line = Some(raw_line);
|
||||
stream_inf_line = Some(line);
|
||||
|
||||
continue;
|
||||
} else if raw_line.starts_with("#EXT") {
|
||||
Line::Tag(raw_line.parse()?)
|
||||
} else if raw_line.starts_with('#') {
|
||||
} 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 {
|
||||
let res = Line::Tag(format!("{}\n{}", first_line, raw_line).parse()?);
|
||||
stream_inf_line = None;
|
||||
res
|
||||
match format!("{}\n{}", first_line, line).parse() {
|
||||
Ok(value) => {
|
||||
return Some(Ok(Line::Tag(value)));
|
||||
}
|
||||
Err(e) => return Some(Err(e)),
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
Line::Uri(raw_line.to_string())
|
||||
return Some(Ok(Line::Uri(line.to_string())));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
result.push(line);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Lines {
|
||||
type IntoIter = ::std::vec::IntoIter<Line>;
|
||||
type Item = Line;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Lines {
|
||||
type Target = Vec<Line>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
impl<'a> From<&'a str> for Lines<'a> {
|
||||
fn from(buffer: &'a str) -> Self {
|
||||
Self {
|
||||
buffer,
|
||||
position: 0,
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Lines {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.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),
|
||||
|
|
|
@ -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::<Lines>()?.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) {
|
||||
|
|
|
@ -285,8 +285,8 @@ fn parse_media_playlist(
|
|||
|
||||
let mut available_key_tags: Vec<crate::tags::ExtXKey> = vec![];
|
||||
|
||||
for (i, line) in input.parse::<Lines>()?.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) {
|
||||
|
|
|
@ -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<ExtXKey>,
|
||||
/// The [`ExtXMap`] tag associated with the media segment.
|
||||
|
|
Loading…
Reference in a new issue