use std::collections::HashMap;
use crate::document::DocumentBuilder;
use crate::namespace::Namespace;
use super::super::error::{TransformError, TransformResult};
use super::EditableNode;
pub struct EditableNodeBuilder {
builder: DocumentBuilder,
depth: usize,
namespaces: HashMap<String, String>,
}
impl EditableNodeBuilder {
pub fn new() -> Self {
Self {
builder: DocumentBuilder::new(),
depth: 0,
namespaces: HashMap::new(),
}
}
pub fn with_namespaces(mut self, namespaces: HashMap<String, String>) -> Self {
self.namespaces = namespaces;
self
}
pub fn set_namespaces(&mut self, namespaces: HashMap<String, String>) {
self.namespaces = namespaces;
}
pub fn start_element(
&mut self,
name: &str,
prefix: Option<&str>,
namespace_uri: Option<&str>,
attributes: Vec<(&str, &str)>,
attribute_ns_info: Vec<(&str, &str, &str)>,
namespace_decls: Vec<Namespace>,
) {
self.builder.start_element(
name,
prefix,
namespace_uri,
attributes,
attribute_ns_info,
namespace_decls,
None,
None,
);
self.depth += 1;
}
pub fn end_element(&mut self) {
self.builder.end_element();
self.depth = self.depth.saturating_sub(1);
}
pub fn text(&mut self, content: &str) {
self.builder.text(content);
}
pub fn cdata(&mut self, content: &str) {
self.builder.cdata(content);
}
pub fn comment(&mut self, content: &str) {
self.builder.comment(content);
}
pub fn is_complete(&self) -> bool {
self.depth == 0
}
pub fn depth(&self) -> usize {
self.depth
}
pub fn build(self) -> TransformResult<EditableNode> {
let doc = self.builder.build();
let root_id = doc
.root_element_id
.ok_or_else(|| TransformError::XmlParse("no root element in subtree".to_string()))?;
if self.namespaces.is_empty() {
Ok(EditableNode::new(doc, root_id))
} else {
Ok(EditableNode::with_namespaces(doc, root_id, self.namespaces))
}
}
}
impl Default for EditableNodeBuilder {
fn default() -> Self {
Self::new()
}
}