mirror of
https://github.com/sile/hls_m3u8.git
synced 2024-11-21 23:01:00 +00:00
removed SingleLineString #9
This commit is contained in:
parent
6ffbe50322
commit
c28d6963a6
8 changed files with 35 additions and 122 deletions
|
@ -3,7 +3,6 @@ use std::ops::{Deref, DerefMut};
|
|||
use std::str::FromStr;
|
||||
|
||||
use crate::tags;
|
||||
use crate::types::SingleLineString;
|
||||
use crate::Error;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -54,7 +53,7 @@ impl FromStr for Lines {
|
|||
continue;
|
||||
}
|
||||
} else {
|
||||
Line::Uri(SingleLineString::new(line)?)
|
||||
Line::Uri(line.trim().to_string())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -92,7 +91,7 @@ impl DerefMut for Lines {
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Line {
|
||||
Tag(Tag),
|
||||
Uri(SingleLineString),
|
||||
Uri(String),
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
|
@ -120,7 +119,7 @@ pub enum Tag {
|
|||
ExtXSessionKey(tags::ExtXSessionKey),
|
||||
ExtXIndependentSegments(tags::ExtXIndependentSegments),
|
||||
ExtXStart(tags::ExtXStart),
|
||||
Unknown(SingleLineString),
|
||||
Unknown(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Tag {
|
||||
|
@ -202,7 +201,7 @@ impl FromStr for Tag {
|
|||
} else if s.starts_with(tags::ExtXStart::PREFIX) {
|
||||
s.parse().map(Tag::ExtXStart)
|
||||
} else {
|
||||
SingleLineString::new(s).map(Tag::Unknown)
|
||||
Ok(Tag::Unknown(s.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use derive_builder::Builder;
|
|||
use crate::tags::{
|
||||
ExtInf, ExtXByteRange, ExtXDateRange, ExtXDiscontinuity, ExtXKey, ExtXMap, ExtXProgramDateTime,
|
||||
};
|
||||
use crate::types::{ProtocolVersion, SingleLineString};
|
||||
use crate::types::ProtocolVersion;
|
||||
|
||||
/// Media segment.
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
|
@ -33,7 +33,7 @@ pub struct MediaSegment {
|
|||
/// Sets an [ExtInf] tag.
|
||||
inf_tag: ExtInf,
|
||||
/// Sets an Uri.
|
||||
uri: SingleLineString,
|
||||
uri: String,
|
||||
}
|
||||
|
||||
impl MediaSegmentBuilder {
|
||||
|
@ -80,7 +80,7 @@ impl MediaSegment {
|
|||
MediaSegmentBuilder::default()
|
||||
}
|
||||
/// Returns the URI of the media segment.
|
||||
pub const fn uri(&self) -> &SingleLineString {
|
||||
pub const fn uri(&self) -> &String {
|
||||
&self.uri
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ use std::str::FromStr;
|
|||
use crate::attribute::AttributePairs;
|
||||
use crate::types::{
|
||||
ClosedCaptions, DecimalFloatingPoint, DecimalResolution, HdcpLevel, ProtocolVersion,
|
||||
SingleLineString,
|
||||
};
|
||||
use crate::utils::{parse_u64, quote, tag, unquote};
|
||||
use crate::Error;
|
||||
|
@ -14,7 +13,7 @@ use crate::Error;
|
|||
/// [4.3.4.2. EXT-X-STREAM-INF]: https://tools.ietf.org/html/rfc8216#section-4.3.4.2
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ExtXStreamInf {
|
||||
uri: SingleLineString,
|
||||
uri: String,
|
||||
bandwidth: u64,
|
||||
average_bandwidth: Option<u64>,
|
||||
codecs: Option<String>,
|
||||
|
@ -33,7 +32,7 @@ impl ExtXStreamInf {
|
|||
/// Makes a new `ExtXStreamInf` tag.
|
||||
pub fn new<T: ToString>(uri: T, bandwidth: u64) -> Self {
|
||||
ExtXStreamInf {
|
||||
uri: SingleLineString::new(uri.to_string()).unwrap(),
|
||||
uri: uri.to_string(),
|
||||
bandwidth,
|
||||
average_bandwidth: None,
|
||||
codecs: None,
|
||||
|
@ -48,7 +47,7 @@ impl ExtXStreamInf {
|
|||
}
|
||||
|
||||
/// Returns the URI that identifies the associated media playlist.
|
||||
pub const fn uri(&self) -> &SingleLineString {
|
||||
pub const fn uri(&self) -> &String {
|
||||
&self.uri
|
||||
}
|
||||
|
||||
|
@ -155,12 +154,10 @@ impl FromStr for ExtXStreamInf {
|
|||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||
let mut lines = input.lines();
|
||||
let first_line = lines.next().ok_or(Error::missing_value("first_line"))?;
|
||||
let second_line = lines.next().ok_or(Error::missing_value("second_line"))?;
|
||||
let uri = lines.next().ok_or(Error::missing_value("second_line"))?;
|
||||
|
||||
let first_line = tag(first_line, Self::PREFIX)?;
|
||||
|
||||
let uri = SingleLineString::new(second_line)?;
|
||||
|
||||
let mut bandwidth = None;
|
||||
let mut average_bandwidth = None;
|
||||
let mut codecs = None;
|
||||
|
@ -194,7 +191,7 @@ impl FromStr for ExtXStreamInf {
|
|||
let bandwidth = bandwidth.ok_or(Error::missing_value("EXT-X-BANDWIDTH"))?;
|
||||
|
||||
Ok(ExtXStreamInf {
|
||||
uri,
|
||||
uri: uri.to_string(),
|
||||
bandwidth,
|
||||
average_bandwidth,
|
||||
codecs,
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::fmt;
|
|||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::types::{DecimalFloatingPoint, ProtocolVersion, SingleLineString};
|
||||
use crate::types::{DecimalFloatingPoint, ProtocolVersion};
|
||||
use crate::utils::tag;
|
||||
use crate::Error;
|
||||
|
||||
|
@ -35,11 +35,10 @@ use crate::Error;
|
|||
/// ```
|
||||
/// use std::time::Duration;
|
||||
/// use hls_m3u8::tags::ExtInf;
|
||||
/// use hls_m3u8::types::SingleLineString;
|
||||
///
|
||||
/// let ext_inf = ExtInf::with_title(
|
||||
/// Duration::from_millis(88),
|
||||
/// SingleLineString::new("title").unwrap()
|
||||
/// "title"
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(ext_inf.duration(), Duration::from_millis(88));
|
||||
|
@ -48,7 +47,7 @@ use crate::Error;
|
|||
#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct ExtInf {
|
||||
duration: Duration,
|
||||
title: Option<SingleLineString>,
|
||||
title: Option<String>,
|
||||
}
|
||||
|
||||
impl ExtInf {
|
||||
|
@ -63,10 +62,10 @@ impl ExtInf {
|
|||
}
|
||||
|
||||
/// Makes a new `ExtInf` tag with the given title.
|
||||
pub const fn with_title(duration: Duration, title: SingleLineString) -> Self {
|
||||
pub fn with_title<T: ToString>(duration: Duration, title: T) -> Self {
|
||||
ExtInf {
|
||||
duration,
|
||||
title: Some(title),
|
||||
title: Some(title.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +75,7 @@ impl ExtInf {
|
|||
}
|
||||
|
||||
/// Returns the title of the associated media segment.
|
||||
pub fn title(&self) -> Option<&SingleLineString> {
|
||||
pub fn title(&self) -> Option<&String> {
|
||||
self.title.as_ref()
|
||||
}
|
||||
|
||||
|
@ -127,7 +126,7 @@ impl FromStr for ExtInf {
|
|||
if tokens[1].trim().is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(SingleLineString::new(tokens[1])?)
|
||||
Some(tokens[1].to_string())
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
@ -160,19 +159,11 @@ mod test {
|
|||
);
|
||||
assert_eq!(
|
||||
"#EXTINF:5.5,title".to_string(),
|
||||
ExtInf::with_title(
|
||||
Duration::from_millis(5500),
|
||||
SingleLineString::new("title").unwrap()
|
||||
)
|
||||
.to_string()
|
||||
ExtInf::with_title(Duration::from_millis(5500), "title").to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
"#EXTINF:5,title".to_string(),
|
||||
ExtInf::with_title(
|
||||
Duration::from_secs(5),
|
||||
SingleLineString::new("title").unwrap()
|
||||
)
|
||||
.to_string()
|
||||
ExtInf::with_title(Duration::from_secs(5), "title").to_string()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -197,17 +188,11 @@ mod test {
|
|||
);
|
||||
assert_eq!(
|
||||
"#EXTINF:5.5,title".parse::<ExtInf>().unwrap(),
|
||||
ExtInf::with_title(
|
||||
Duration::from_millis(5500),
|
||||
SingleLineString::new("title").unwrap()
|
||||
)
|
||||
ExtInf::with_title(Duration::from_millis(5500), "title")
|
||||
);
|
||||
assert_eq!(
|
||||
"#EXTINF:5,title".parse::<ExtInf>().unwrap(),
|
||||
ExtInf::with_title(
|
||||
Duration::from_secs(5),
|
||||
SingleLineString::new("title").unwrap()
|
||||
)
|
||||
ExtInf::with_title(Duration::from_secs(5), "title")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -215,12 +200,8 @@ mod test {
|
|||
fn test_title() {
|
||||
assert_eq!(ExtInf::new(Duration::from_secs(5)).title(), None);
|
||||
assert_eq!(
|
||||
ExtInf::with_title(
|
||||
Duration::from_secs(5),
|
||||
SingleLineString::new("title").unwrap()
|
||||
)
|
||||
.title(),
|
||||
Some(&SingleLineString::new("title").unwrap())
|
||||
ExtInf::with_title(Duration::from_secs(5), "title").title(),
|
||||
Some(&"title".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::types::{ProtocolVersion, SingleLineString};
|
||||
use crate::types::ProtocolVersion;
|
||||
use crate::utils::tag;
|
||||
use crate::Error;
|
||||
|
||||
|
@ -9,21 +9,19 @@ use crate::Error;
|
|||
///
|
||||
/// [4.3.2.6. EXT-X-PROGRAM-DATE-TIME]: https://tools.ietf.org/html/rfc8216#section-4.3.2.6
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ExtXProgramDateTime {
|
||||
date_time: SingleLineString,
|
||||
}
|
||||
pub struct ExtXProgramDateTime(String);
|
||||
|
||||
impl ExtXProgramDateTime {
|
||||
pub(crate) const PREFIX: &'static str = "#EXT-X-PROGRAM-DATE-TIME:";
|
||||
|
||||
/// Makes a new `ExtXProgramDateTime` tag.
|
||||
pub const fn new(date_time: SingleLineString) -> Self {
|
||||
ExtXProgramDateTime { date_time }
|
||||
pub fn new<T: ToString>(date_time: T) -> Self {
|
||||
Self(date_time.to_string())
|
||||
}
|
||||
|
||||
/// Returns the date-time of the first sample of the associated media segment.
|
||||
pub const fn date_time(&self) -> &SingleLineString {
|
||||
&self.date_time
|
||||
pub const fn date_time(&self) -> &String {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Returns the protocol compatibility version that this tag requires.
|
||||
|
@ -34,7 +32,7 @@ impl ExtXProgramDateTime {
|
|||
|
||||
impl fmt::Display for ExtXProgramDateTime {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}{}", Self::PREFIX, self.date_time)
|
||||
write!(f, "{}{}", Self::PREFIX, self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,9 +44,7 @@ impl FromStr for ExtXProgramDateTime {
|
|||
|
||||
// TODO: parse with chrono
|
||||
|
||||
Ok(ExtXProgramDateTime {
|
||||
date_time: (SingleLineString::new(input))?,
|
||||
})
|
||||
Ok(Self::new(input))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ mod media_type;
|
|||
mod protocol_version;
|
||||
mod session_data;
|
||||
mod signed_decimal_floating_point;
|
||||
mod single_line_string;
|
||||
|
||||
pub use byte_range::*;
|
||||
pub use closed_captions::*;
|
||||
|
@ -29,4 +28,3 @@ pub use media_type::*;
|
|||
pub use protocol_version::*;
|
||||
pub use session_data::*;
|
||||
pub use signed_decimal_floating_point::*;
|
||||
pub use single_line_string::*;
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
use crate::Error;
|
||||
use std::fmt;
|
||||
use std::ops::Deref;
|
||||
|
||||
/// String that represents a single line in a playlist file.
|
||||
///
|
||||
/// See: [4.1. Definition of a Playlist]
|
||||
///
|
||||
/// [4.1. Definition of a Playlist]: https://tools.ietf.org/html/rfc8216#section-4.1
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct SingleLineString(String);
|
||||
|
||||
impl SingleLineString {
|
||||
/// Makes a new `SingleLineString` instance.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the given string contains any control characters,
|
||||
/// this function will return an error which has the kind `ErrorKind::InvalidInput`.
|
||||
pub fn new<T: Into<String>>(s: T) -> crate::Result<Self> {
|
||||
let s = s.into();
|
||||
if s.chars().any(|c| c.is_control()) {
|
||||
Err(Error::invalid_input())
|
||||
} else {
|
||||
Ok(SingleLineString(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for SingleLineString {
|
||||
type Target = str;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for SingleLineString {
|
||||
fn as_ref(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SingleLineString {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn single_line_string() {
|
||||
assert!(SingleLineString::new("foo").is_ok());
|
||||
assert!(SingleLineString::new("b\rar").is_err());
|
||||
}
|
||||
}
|
|
@ -37,11 +37,11 @@ fn test_simple_playlist() {
|
|||
|
||||
assert_eq!(
|
||||
media_playlist.segments()[0].uri(),
|
||||
&SingleLineString::new("http://media.example.com/entire1.ts").unwrap()
|
||||
&"http://media.example.com/entire1.ts".to_string()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
media_playlist.segments()[1].uri(),
|
||||
&SingleLineString::new("http://media.example.com/entire2.ts").unwrap()
|
||||
&"http://media.example.com/entire2.ts".to_string()
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue