1
0
Fork 0
mirror of https://github.com/sile/hls_m3u8.git synced 2024-06-15 11:30:35 +00:00
hls_m3u8/src/attribute.rs

77 lines
2.1 KiB
Rust
Raw Normal View History

2018-02-14 15:24:35 +00:00
use std::collections::HashSet;
use std::str;
2018-02-11 06:10:52 +00:00
2018-02-14 15:24:35 +00:00
use {ErrorKind, Result};
2018-02-11 06:10:52 +00:00
#[derive(Debug)]
pub struct AttributePairs<'a> {
input: &'a str,
2018-02-14 15:24:35 +00:00
visited_keys: HashSet<&'a str>,
2018-02-11 06:10:52 +00:00
}
impl<'a> AttributePairs<'a> {
pub fn parse(input: &'a str) -> Self {
2018-02-14 15:24:35 +00:00
AttributePairs {
input,
visited_keys: HashSet::new(),
}
2018-02-11 06:10:52 +00:00
}
fn parse_name(&mut self) -> Result<&'a str> {
for i in 0..self.input.len() {
match self.input.as_bytes()[i] {
b'=' => {
let (key, _) = self.input.split_at(i);
let (_, rest) = self.input.split_at(i + 1);
self.input = rest;
return Ok(key);
}
b'A'...b'Z' | b'0'...b'9' | b'-' => {}
_ => track_panic!(
ErrorKind::InvalidInput,
"Malformed attribute name: {:?}",
self.input
),
}
}
track_panic!(
ErrorKind::InvalidInput,
"No attribute value: {:?}",
self.input
);
}
fn parse_raw_value(&mut self) -> &'a str {
let (value_end, next) = if let Some(i) = self.input.bytes().position(|c| c == b',') {
(i, i + 1)
} else {
(self.input.len(), self.input.len())
};
let (value, _) = self.input.split_at(value_end);
let (_, rest) = self.input.split_at(next);
self.input = rest;
value
}
}
impl<'a> Iterator for AttributePairs<'a> {
type Item = Result<(&'a str, &'a str)>;
fn next(&mut self) -> Option<Self::Item> {
if self.input.is_empty() {
return None;
}
let result = || -> Result<(&'a str, &'a str)> {
let key = track!(self.parse_name())?;
2018-02-14 15:24:35 +00:00
track_assert!(
self.visited_keys.insert(key),
ErrorKind::InvalidInput,
"Duplicate attribute key: {:?}",
key
);
2018-02-11 06:10:52 +00:00
let value = self.parse_raw_value();
Ok((key, value))
}();
Some(result)
}
}