1
0
Fork 0
mirror of https://github.com/sile/hls_m3u8.git synced 2024-05-18 16:28:20 +00:00

rewrite Lines to reduce allocations

This commit is contained in:
Luro02 2020-02-02 14:33:57 +01:00
parent 006f36ff47
commit e6a1103d24
No known key found for this signature in database
GPG key ID: B66FD4F74501A9CF
5 changed files with 59 additions and 61 deletions

View file

@ -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,

View file

@ -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) {
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<Line>;
type Item = Line;
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 }
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),

View file

@ -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) {

View file

@ -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) {

View file

@ -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.