1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
/*
This file is part of jellything (https://codeberg.org/metamuffin/jellything)
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
use crate::{matroska::MatroskaTag, Master, Result};
pub struct Unflat<'a> {
pub item: MatroskaTag,
pub children: Option<Unflatten<'a>>,
pub position: Option<u64>,
}
pub struct Unflatten<'a> {
inner: &'a mut dyn Iterator<Item = Result<(Option<u64>, MatroskaTag)>>,
stop: bool,
end: Option<MatroskaTag>,
}
impl<'a> Unflatten<'a> {
pub fn new(inner: &'a mut dyn Iterator<Item = Result<(Option<u64>, MatroskaTag)>>) -> Self {
Self {
inner,
stop: false,
end: None,
}
}
pub fn new_with_end(
inner: &'a mut dyn Iterator<Item = Result<(Option<u64>, MatroskaTag)>>,
start: MatroskaTag,
) -> Self {
Self {
inner,
stop: false,
end: Some(MatroskaTag::construct_master(start.id(), Master::End).unwrap()),
}
}
pub fn exit_dirty(&mut self) {
self.stop = true;
}
pub fn n(&mut self) -> Option<Result<Unflat>> {
if self.stop {
return None;
}
match self.inner.next() {
None => None,
Some(Err(e)) => Some(Err(e)),
Some(Ok((position, item))) => {
let master = MatroskaTag::is_master(item.id()).unwrap();
if Some(&item) == self.end.as_ref() {
self.stop = true;
None
} else {
Some(Ok(Unflat {
position,
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 self.n().is_some() {}
}
}
|