aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-01-15 11:18:19 +0100
committermetamuffin <metamuffin@disroot.org>2023-01-15 11:18:19 +0100
commit3fe89c28de457407483ed9c483c6a660f8294250 (patch)
treec4408dd076c7c1cdf2321b3723f06287ead547ea
parentba6942c04945c2d9b9d4672a68c85d43ade0b5c8 (diff)
downloadjellything-3fe89c28de457407483ed9c483c6a660f8294250.tar
jellything-3fe89c28de457407483ed9c483c6a660f8294250.tar.bz2
jellything-3fe89c28de457407483ed9c483c6a660f8294250.tar.zst
unflatten
-rw-r--r--ebml/src/unflatten.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/ebml/src/unflatten.rs b/ebml/src/unflatten.rs
new file mode 100644
index 0000000..e1dd0a2
--- /dev/null
+++ b/ebml/src/unflatten.rs
@@ -0,0 +1,64 @@
+use crate::{matroska::MatroskaTag, Master};
+use anyhow::Result;
+
+pub struct Unflat<'a> {
+ pub item: MatroskaTag,
+ pub children: Option<Unflatten<'a>>,
+}
+
+pub struct Unflatten<'a> {
+ inner: &'a mut dyn Iterator<Item = Result<MatroskaTag>>,
+ stop: bool,
+ end: Option<MatroskaTag>,
+}
+
+impl<'a> Unflatten<'a> {
+ pub fn new(inner: &'a mut dyn Iterator<Item = Result<MatroskaTag>>) -> Self {
+ Self {
+ inner,
+ stop: false,
+ end: None,
+ }
+ }
+
+ pub fn next(&mut self) -> Option<Result<Unflat>> {
+ if self.stop {
+ return None;
+ }
+ match self.inner.next() {
+ None => None,
+ Some(Err(e)) => Some(Err(e)),
+ Some(Ok(item)) => {
+ let master = MatroskaTag::is_master(item.id()).unwrap();
+ if Some(&item) == self.end.as_ref() {
+ self.stop = true;
+ None
+ } else {
+ Some(Ok(Unflat {
+ children: if master {
+ let end =
+ MatroskaTag::construct_master(item.id(), Master::End).unwrap();
+ if end == item {
+ return None;
+ }
+ Some(Unflatten {
+ inner: self.inner,
+ stop: false,
+ end: Some(end),
+ })
+ } else {
+ None
+ },
+ item,
+ }))
+ }
+ }
+ }
+ }
+}
+
+impl Drop for Unflatten<'_> {
+ fn drop(&mut self) {
+ while let Some(_) = self.next() {}
+ }
+}