diff --git a/src/element.rs b/src/element.rs index 2b149a8..1c04c98 100644 --- a/src/element.rs +++ b/src/element.rs @@ -58,7 +58,8 @@ pub struct Element { // namespace: String, // hashmap of explicit namespace declarations on the element itself only // possibly not needed as can be calculated at write time depending on context and qualified namespace, and for reading, element validity and namespaces are kept track of by the reader. - pub namespace_declarations: HashSet, + // change this to custom namespace declarations only, so you can override the definition of namespaces if you wish + pub namespace_declaration_overrides: HashSet, // attributes can be in a different namespace than the element. how to make sure they are valid? // maybe include the namespace instead of or with the prefix // you can calculate the prefix from the namespaced name and the current writer context diff --git a/src/error.rs b/src/error.rs index eda527e..85b5d70 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,9 @@ use std::{num::ParseIntError, str::Utf8Error}; -use crate::element::{Content, Name, NamespaceDeclaration}; +use crate::{ + element::{Content, Name, NamespaceDeclaration}, + Element, +}; #[derive(Debug)] pub enum Error { diff --git a/src/reader.rs b/src/reader.rs index ee8d491..e6bb57c 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -436,7 +436,7 @@ impl Reader { return Ok(Element { name: element_name, - namespace_declarations: element_namespace_declarations, + namespace_declaration_overrides: element_namespace_declarations, attributes, content: Vec::new(), }); @@ -657,7 +657,7 @@ impl Reader { return Ok(Element { name: element_name, - namespace_declarations: element_namespace_declarations, + namespace_declaration_overrides: element_namespace_declarations, attributes, content, }); diff --git a/src/writer.rs b/src/writer.rs index e319fdc..8b45869 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -93,20 +93,38 @@ impl Writer { } pub async fn write_empty(&mut self, element: &Element) -> Result<()> { - let namespace_declarations_stack: Vec<_> = self + let mut namespace_declarations_stack: Vec<_> = self .namespace_declarations .iter() .flatten() - .chain(&element.namespace_declarations) + .chain(&element.namespace_declaration_overrides) .collect(); + let mut namespace_declarations = element.namespace_declaration_overrides.clone(); + + let default_namespace_declaration; let prefix; if let Some(namespace) = &element.name.namespace { - let name_namespace_declaration = namespace_declarations_stack + if let Some(name_namespace_declaration) = namespace_declarations_stack .iter() .rfind(|namespace_declaration| namespace_declaration.namespace == *namespace) - .ok_or(Error::UndeclaredNamespace(namespace.clone()))?; - prefix = name_namespace_declaration.prefix.as_ref(); + { + prefix = name_namespace_declaration.prefix.as_ref(); + } else { + default_namespace_declaration = NamespaceDeclaration { + prefix: None, + namespace: namespace.clone(), + }; + if namespace_declarations.insert(default_namespace_declaration.clone()) { + namespace_declarations_stack.push(&default_namespace_declaration); + prefix = None + } else { + return Err(Error::DuplicateNameSpaceDeclaration(NamespaceDeclaration { + prefix: None, + namespace: namespace.clone(), + })); + } + } } else { prefix = None } @@ -125,7 +143,7 @@ impl Writer { let mut attributes = Vec::new(); - for namespace_declaration in &element.namespace_declarations { + for namespace_declaration in namespace_declarations.iter() { let ns_name = namespace_declaration .prefix .as_ref() @@ -180,20 +198,38 @@ impl Writer { } pub async fn write_element_start(&mut self, element: &Element) -> Result<()> { - let namespace_declarations_stack: Vec<_> = self + let mut namespace_declarations_stack: Vec<_> = self .namespace_declarations .iter() .flatten() - .chain(&element.namespace_declarations) + .chain(&element.namespace_declaration_overrides) .collect(); + let mut namespace_declarations = element.namespace_declaration_overrides.clone(); + + let default_namespace_declaration; let prefix; if let Some(namespace) = &element.name.namespace { - let name_namespace_declaration = namespace_declarations_stack + if let Some(name_namespace_declaration) = namespace_declarations_stack .iter() .rfind(|namespace_declaration| namespace_declaration.namespace == *namespace) - .ok_or(Error::UndeclaredNamespace(namespace.clone()))?; - prefix = name_namespace_declaration.prefix.as_ref(); + { + prefix = name_namespace_declaration.prefix.as_ref(); + } else { + default_namespace_declaration = NamespaceDeclaration { + prefix: None, + namespace: namespace.clone(), + }; + if namespace_declarations.insert(default_namespace_declaration.clone()) { + namespace_declarations_stack.push(&default_namespace_declaration); + prefix = None + } else { + return Err(Error::DuplicateNameSpaceDeclaration(NamespaceDeclaration { + prefix: None, + namespace: namespace.clone(), + })); + } + } } else { prefix = None } @@ -212,7 +248,7 @@ impl Writer { let mut attributes = Vec::new(); - for namespace_declaration in &element.namespace_declarations { + for namespace_declaration in namespace_declarations.iter() { let ns_name = namespace_declaration .prefix .as_ref() @@ -265,7 +301,7 @@ impl Writer { self.depth.push(element.name.clone()); self.namespace_declarations - .push(element.namespace_declarations.clone()); + .push(namespace_declarations.clone()); Ok(()) }