Don't repeat yourself.
This commit is contained in:
parent
bd1ea56cc3
commit
7a9a16e598
|
@ -20,61 +20,62 @@ pub struct XMLDocumentData<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gc> XMLDocument<'gc> {
|
impl<'gc> XMLDocument<'gc> {
|
||||||
|
/// Construct a new, empty XML document.
|
||||||
pub fn new(mc: MutationContext<'gc, '_>) -> Self {
|
pub fn new(mc: MutationContext<'gc, '_>) -> Self {
|
||||||
Self(GcCell::allocate(mc, XMLDocumentData { roots: Vec::new() }))
|
Self(GcCell::allocate(mc, XMLDocumentData { roots: Vec::new() }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure that a newly-encountered node is added to an ongoing parsing
|
||||||
|
/// stack, or to the document itself if the parsing stack is empty.
|
||||||
|
fn add_child_to_tree(
|
||||||
|
&mut self,
|
||||||
|
mc: MutationContext<'gc, '_>,
|
||||||
|
open_tags: &mut Vec<XMLNode<'gc>>,
|
||||||
|
child: XMLNode<'gc>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
if let Some(node) = open_tags.last_mut() {
|
||||||
|
node.append_child(mc, child)?;
|
||||||
|
} else {
|
||||||
|
self.0.write(mc).roots.push(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_str(mc: MutationContext<'gc, '_>, data: &str) -> Result<Self, Error> {
|
pub fn from_str(mc: MutationContext<'gc, '_>, data: &str) -> Result<Self, Error> {
|
||||||
let mut parser = Reader::from_str(data);
|
let mut parser = Reader::from_str(data);
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let mut roots = Vec::new();
|
let mut document = Self::new(mc);
|
||||||
let mut open_tags: Vec<XMLNode<'gc>> = Vec::new();
|
let mut open_tags: Vec<XMLNode<'gc>> = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match parser.read_event(&mut buf)? {
|
match parser.read_event(&mut buf)? {
|
||||||
Event::Start(bs) => {
|
Event::Start(bs) => {
|
||||||
let child = XMLNode::from_start_event(mc, bs)?;
|
let child = XMLNode::from_start_event(mc, bs)?;
|
||||||
if let Some(node) = open_tags.last_mut() {
|
document.add_child_to_tree(mc, &mut open_tags, child)?;
|
||||||
node.append_child(mc, child)?;
|
|
||||||
} else {
|
|
||||||
roots.push(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
open_tags.push(child);
|
open_tags.push(child);
|
||||||
}
|
}
|
||||||
Event::Empty(bs) => {
|
Event::Empty(bs) => {
|
||||||
let child = XMLNode::from_start_event(mc, bs)?;
|
let child = XMLNode::from_start_event(mc, bs)?;
|
||||||
if let Some(node) = open_tags.last_mut() {
|
document.add_child_to_tree(mc, &mut open_tags, child)?;
|
||||||
node.append_child(mc, child)?;
|
|
||||||
} else {
|
|
||||||
roots.push(child);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Event::End(_) => {
|
Event::End(_) => {
|
||||||
open_tags.pop();
|
open_tags.pop();
|
||||||
}
|
}
|
||||||
Event::Text(bt) => {
|
Event::Text(bt) => {
|
||||||
let child = XMLNode::text_from_text_event(mc, bt)?;
|
let child = XMLNode::text_from_text_event(mc, bt)?;
|
||||||
if let Some(node) = open_tags.last_mut() {
|
document.add_child_to_tree(mc, &mut open_tags, child)?;
|
||||||
node.append_child(mc, child)?;
|
|
||||||
} else {
|
|
||||||
roots.push(child);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Event::Comment(bt) => {
|
Event::Comment(bt) => {
|
||||||
let child = XMLNode::comment_from_text_event(mc, bt)?;
|
let child = XMLNode::comment_from_text_event(mc, bt)?;
|
||||||
if let Some(node) = open_tags.last_mut() {
|
document.add_child_to_tree(mc, &mut open_tags, child)?;
|
||||||
node.append_child(mc, child)?;
|
|
||||||
} else {
|
|
||||||
roots.push(child);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Event::Eof => break,
|
Event::Eof => break,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self(GcCell::allocate(mc, XMLDocumentData { roots })))
|
Ok(document)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator that yields the document's root nodes.
|
/// Returns an iterator that yields the document's root nodes.
|
||||||
|
|
Loading…
Reference in New Issue