add ElementBodyBuilder
This commit is contained in:
parent
104ee37933
commit
3fc0e92f95
2 changed files with 65 additions and 7 deletions
55
src/main.rs
55
src/main.rs
|
|
@ -1092,4 +1092,59 @@ impl TextLineFontKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ElementBodyBuilder<'a> {
|
||||
containing_element: &'a mut xml_tree::Element,
|
||||
stack: Vec<xml_tree::Element>,
|
||||
}
|
||||
|
||||
impl<'a> ElementBodyBuilder<'a> {
|
||||
fn new(containing_element: &'a mut xml_tree::Element) -> Self {
|
||||
Self {
|
||||
containing_element,
|
||||
stack: Vec::with_capacity(5),
|
||||
}
|
||||
}
|
||||
fn shrink_stack(&mut self, new_len: usize) {
|
||||
while new_len < self.stack.len() {
|
||||
let Some(element) = self.stack.pop() else {
|
||||
unreachable!();
|
||||
};
|
||||
self.insert_point().children.push(element);
|
||||
}
|
||||
}
|
||||
fn set_tag_stack<'b>(&mut self, tag_stack: impl IntoIterator<Item = &'b str>) {
|
||||
let mut new_len = 0;
|
||||
for (i, tag) in tag_stack.into_iter().enumerate() {
|
||||
new_len = i + 1;
|
||||
if i >= self.stack.len() {
|
||||
self.stack.push(xml_tree::Element::new(tag.into(), []));
|
||||
} else if self.stack[i].tag.normal() != Some(tag) {
|
||||
self.shrink_stack(new_len);
|
||||
}
|
||||
}
|
||||
self.shrink_stack(new_len);
|
||||
}
|
||||
fn write_text(&mut self, text: impl Borrow<str>) {
|
||||
let text = text.borrow();
|
||||
let insert_point = self.insert_point();
|
||||
if let Some(child) = insert_point.children.last_mut() {
|
||||
child.tail += text;
|
||||
} else {
|
||||
insert_point.text += text;
|
||||
}
|
||||
}
|
||||
fn insert_point(&mut self) -> &mut xml_tree::Element {
|
||||
self.stack.last_mut().unwrap_or(self.containing_element)
|
||||
}
|
||||
fn scope<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
|
||||
let retval = f(self);
|
||||
self.flush();
|
||||
retval
|
||||
}
|
||||
fn flush(&mut self) {
|
||||
self.set_tag_stack([]);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -157,6 +157,15 @@ impl fmt::Display for Element {
|
|||
}
|
||||
|
||||
impl Element {
|
||||
pub(crate) fn new(tag: String, attrib: impl IntoIterator<Item = (String, String)>) -> Self {
|
||||
Self {
|
||||
tag: ElementTag::Normal(tag),
|
||||
attrib: Vec::from_iter(attrib),
|
||||
text: String::new(),
|
||||
children: Vec::new(),
|
||||
tail: String::new(),
|
||||
}
|
||||
}
|
||||
/// equivalent to python `"".join(self.itertext())`
|
||||
pub(crate) fn inner_text(&self) -> String {
|
||||
let mut retval = String::new();
|
||||
|
|
@ -186,13 +195,7 @@ impl Element {
|
|||
tag: String,
|
||||
attrib: impl IntoIterator<Item = (String, String)>,
|
||||
) -> &mut Self {
|
||||
self.children.push(Self {
|
||||
tag: ElementTag::Normal(tag),
|
||||
attrib: Vec::from_iter(attrib),
|
||||
text: String::new(),
|
||||
children: Vec::new(),
|
||||
tail: String::new(),
|
||||
});
|
||||
self.children.push(Self::new(tag, attrib));
|
||||
self.children.last_mut().expect("just pushed")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue