move decode_element & iterator creation onto Schema trait
This commit is contained in:
parent
128192c622
commit
fd0fb41acf
1 changed files with 45 additions and 45 deletions
76
src/lib.rs
76
src/lib.rs
|
@ -96,36 +96,15 @@ pub fn decode_tag(bytes: &[u8]) -> Result<Option<(u64, Varint, usize)>, Error> {
|
||||||
pub trait Schema<'a> {
|
pub trait Schema<'a> {
|
||||||
type Element: 'a;
|
type Element: 'a;
|
||||||
|
|
||||||
fn should_unwrap(element_id: u64) -> bool;
|
fn should_unwrap(&self, element_id: u64) -> bool;
|
||||||
fn decode<'b: 'a>(element_id: u64, bytes: &'b[u8]) -> Result<Self::Element, Error>;
|
fn decode<'b: 'a>(&self, element_id: u64, bytes: &'b[u8]) -> Result<Self::Element, Error>;
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Webm;
|
fn decode_element<'b: 'a>(&self, bytes: &'b[u8]) -> Result<Option<(Self::Element, usize)>, Error> {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub enum WebmElement<'a> {
|
|
||||||
Unknown(u64, &'a[u8])
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Schema<'a> for Webm {
|
|
||||||
type Element = WebmElement<'a>;
|
|
||||||
|
|
||||||
fn should_unwrap(element_id: u64) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decode<'b: 'a>(element_id: u64, bytes: &'b[u8]) -> Result<WebmElement<'a>, Error> {
|
|
||||||
// dummy
|
|
||||||
Ok(WebmElement::Unknown(element_id, bytes))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decode_element<'a, 'b: 'a, T: Schema<'a>>(bytes: &'b[u8]) -> Result<Option<(T::Element, usize)>, Error> {
|
|
||||||
match decode_tag(bytes) {
|
match decode_tag(bytes) {
|
||||||
Ok(None) => Ok(None),
|
Ok(None) => Ok(None),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
Ok(Some((element_id, payload_size_tag, tag_size))) => {
|
Ok(Some((element_id, payload_size_tag, tag_size))) => {
|
||||||
let should_unwrap = T::should_unwrap(element_id);
|
let should_unwrap = self.should_unwrap(element_id);
|
||||||
|
|
||||||
let payload_size = match (should_unwrap, payload_size_tag) {
|
let payload_size = match (should_unwrap, payload_size_tag) {
|
||||||
(true, _) => 0,
|
(true, _) => 0,
|
||||||
|
@ -139,7 +118,7 @@ pub fn decode_element<'a, 'b: 'a, T: Schema<'a>>(bytes: &'b[u8]) -> Result<Optio
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
match T::decode(element_id, &bytes[tag_size..element_size]) {
|
match self.decode(element_id, &bytes[tag_size..element_size]) {
|
||||||
Ok(element) => Ok(Some((element, element_size))),
|
Ok(element) => Ok(Some((element, element_size))),
|
||||||
Err(error) => Err(error)
|
Err(error) => Err(error)
|
||||||
}
|
}
|
||||||
|
@ -147,27 +126,48 @@ pub fn decode_element<'a, 'b: 'a, T: Schema<'a>>(bytes: &'b[u8]) -> Result<Optio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EbmlIterator<'b, T: Schema<'b>> {
|
fn iter_for<'b: 'a>(self, bytes: &'b[u8]) -> EbmlIterator<'a, Self>
|
||||||
schema: std::marker::PhantomData<T>,
|
where Self: Sized
|
||||||
slice: &'b[u8],
|
{
|
||||||
position: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'b, T: Schema<'b>> EbmlIterator<'b, T> {
|
|
||||||
pub fn new(bytes: &'b[u8]) -> Self {
|
|
||||||
EbmlIterator {
|
EbmlIterator {
|
||||||
schema: std::marker::PhantomData,
|
schema: self,
|
||||||
slice: bytes,
|
slice: bytes,
|
||||||
position: 0
|
position: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Webm;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum WebmElement<'a> {
|
||||||
|
Unknown(u64, &'a[u8])
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Schema<'a> for Webm {
|
||||||
|
type Element = WebmElement<'a>;
|
||||||
|
|
||||||
|
fn should_unwrap(&self, element_id: u64) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode<'b: 'a>(&self, element_id: u64, bytes: &'b[u8]) -> Result<WebmElement<'a>, Error> {
|
||||||
|
// dummy
|
||||||
|
Ok(WebmElement::Unknown(element_id, bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct EbmlIterator<'b, T: Schema<'b>> {
|
||||||
|
schema: T,
|
||||||
|
slice: &'b[u8],
|
||||||
|
position: usize,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'b, T: Schema<'b>> Iterator for EbmlIterator<'b, T> {
|
impl<'b, T: Schema<'b>> Iterator for EbmlIterator<'b, T> {
|
||||||
type Item = T::Element;
|
type Item = T::Element;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<T::Element> {
|
fn next(&mut self) -> Option<T::Element> {
|
||||||
match decode_element::<T>(&self.slice[self.position..]) {
|
match self.schema.decode_element(&self.slice[self.position..]) {
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
Ok(None) => None,
|
Ok(None) => None,
|
||||||
Ok(Some((element, element_size))) => {
|
Ok(Some((element, element_size))) => {
|
||||||
|
@ -249,7 +249,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_sanity_test() {
|
fn decode_sanity_test() {
|
||||||
let decoded = decode_element::<Webm>(TEST_FILE);
|
let decoded = Webm.decode_element(TEST_FILE);
|
||||||
if let Ok(Some((WebmElement::Unknown(tag, slice), element_size))) = decoded {
|
if let Ok(Some((WebmElement::Unknown(tag, slice), element_size))) = decoded {
|
||||||
assert_eq!(tag, 0x0A45DFA3); // EBML tag, sans the length indicator bit
|
assert_eq!(tag, 0x0A45DFA3); // EBML tag, sans the length indicator bit
|
||||||
assert_eq!(slice.len(), 31); // known header payload length
|
assert_eq!(slice.len(), 31); // known header payload length
|
||||||
|
@ -273,7 +273,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_webm_test1() {
|
fn decode_webm_test1() {
|
||||||
let mut iter = EbmlIterator::<Webm>::new(TEST_FILE);
|
let mut iter = Webm.iter_for(TEST_FILE);
|
||||||
// EBML Header
|
// EBML Header
|
||||||
assert_webm_blob(iter.next(), 0x0A45DFA3, 31);
|
assert_webm_blob(iter.next(), 0x0A45DFA3, 31);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue