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

Add attributes

This commit is contained in:
Takeru Ohta 2018-02-12 16:05:21 +09:00
parent b192c762ec
commit e933d8e013
2 changed files with 836 additions and 78 deletions

View file

@ -1,5 +1,8 @@
use std::fmt;
use std::str::{self, FromStr};
use std::time::Duration;
use std::u8;
use trackable::error::ErrorKindExt;
use {Error, ErrorKind, Result};
@ -56,6 +59,7 @@ impl<'a> Iterator for AttributePairs<'a> {
}
let result = || -> Result<(&'a str, &'a str)> {
// TODO: check key duplications
let key = track!(self.parse_name())?;
let value = self.parse_raw_value();
Ok((key, value))
@ -93,3 +97,126 @@ impl FromStr for QuotedString {
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct HexadecimalSequence(Vec<u8>);
impl fmt::Display for HexadecimalSequence {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "0x")?;
for b in &self.0 {
write!(f, "{:02x}", b)?;
}
Ok(())
}
}
impl FromStr for HexadecimalSequence {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
track_assert!(
s.starts_with("0x") || s.starts_with("0X"),
ErrorKind::InvalidInput
);
track_assert!(s.len() % 2 == 0, ErrorKind::InvalidInput);
let mut v = Vec::with_capacity(s.len() / 2 - 1);
for c in s.as_bytes().chunks(2).skip(1) {
let d = track!(str::from_utf8(c).map_err(|e| ErrorKind::InvalidInput.cause(e)))?;
let b =
track!(u8::from_str_radix(d, 16).map_err(|e| ErrorKind::InvalidInput.cause(e)))?;
v.push(b);
}
Ok(HexadecimalSequence(v))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DecimalInteger(u64);
impl fmt::Display for DecimalInteger {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl FromStr for DecimalInteger {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
let n = track!(s.parse().map_err(|e| ErrorKind::InvalidInput.cause(e)))?;
Ok(DecimalInteger(n))
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct DecimalFloatingPoint(f64);
impl DecimalFloatingPoint {
pub fn to_duration(&self) -> Duration {
let secs = self.0 as u64;
let nanos = (self.0.fract() * 1_000_000_000.0) as u32;
Duration::new(secs, nanos)
}
pub fn from_duration(duration: Duration) -> Self {
let n = (duration.as_secs() as f64) + (duration.subsec_nanos() as f64 / 1_000_000_000.0);
DecimalFloatingPoint(n)
}
}
impl Eq for DecimalFloatingPoint {}
impl fmt::Display for DecimalFloatingPoint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl FromStr for DecimalFloatingPoint {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
track_assert!(
s.chars().all(|c| match c {
'0'...'9' | '.' => true,
_ => false,
}),
ErrorKind::InvalidInput
);
let n = track!(s.parse().map_err(|e| ErrorKind::InvalidInput.cause(e)))?;
Ok(DecimalFloatingPoint(n))
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct SignedDecimalFloatingPoint(f64);
impl Eq for SignedDecimalFloatingPoint {}
impl fmt::Display for SignedDecimalFloatingPoint {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl FromStr for SignedDecimalFloatingPoint {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
track_assert!(
s.chars().all(|c| match c {
'0'...'9' | '.' | '-' => true,
_ => false,
}),
ErrorKind::InvalidInput
);
let n = track!(s.parse().map_err(|e| ErrorKind::InvalidInput.cause(e)))?;
Ok(SignedDecimalFloatingPoint(n))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DecimalResolution {
pub width: usize,
pub height: usize,
}
impl fmt::Display for DecimalResolution {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}x{}", self.width, self.height)
}
}
impl FromStr for DecimalResolution {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
let mut tokens = s.splitn(2, 'x');
let width = tokens.next().expect("Never fails");
let height = track_assert_some!(tokens.next(), ErrorKind::InvalidInput);
Ok(DecimalResolution {
width: track!(width.parse().map_err(|e| ErrorKind::InvalidInput.cause(e)))?,
height: track!(height.parse().map_err(|e| ErrorKind::InvalidInput.cause(e)))?,
})
}
}

File diff suppressed because it is too large Load diff