Centralize serializer prefix logic in one place

This commit is contained in:
Dirkjan Ochtman 2022-09-07 12:10:01 +02:00
parent 110605ba99
commit 7d241959d8
2 changed files with 28 additions and 25 deletions

View File

@ -49,14 +49,14 @@ pub fn to_xml(input: &syn::DeriveInput) -> proc_macro2::TokenStream {
serializer: &mut instant_xml::Serializer<W>,
) -> Result<(), instant_xml::Error> {
// Start tag
match serializer.default_ns() == #default_namespace {
true => serializer.write_start(None, #root_name, None)?,
false => serializer.write_start(None, #root_name, Some(#default_namespace))?,
}
let prefix = serializer.write_start(#root_name, #default_namespace, false)?;
debug_assert_eq!(prefix, None);
// Set up element context, this will also emit namespace declarations
#context
let old = serializer.push(new)?;
// Finalize start element
#attributes
serializer.end_start()?;
@ -110,15 +110,7 @@ fn process_named_field(
self.#field_value.serialize(serializer)?;
}
::instant_xml::Kind::Scalar => {
let (prefix, ns) = match serializer.default_ns() == #ns {
true => (None, None),
false => match serializer.prefix(#ns) {
Some(prefix) => (Some(prefix), None),
None => (None, Some(#ns)),
},
};
serializer.write_start(prefix, #name, ns)?;
let prefix = serializer.write_start(#name, #ns, true)?;
serializer.end_start()?;
self.#field_value.serialize(serializer)?;
serializer.write_close(prefix, #name)?;

View File

@ -30,26 +30,37 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> {
pub fn write_start(
&mut self,
prefix: Option<&str>,
name: &str,
ns: Option<&str>,
) -> Result<(), Error> {
ns: &str,
scalar: bool,
) -> Result<Option<&'static str>, Error> {
if self.state != State::Element {
return Err(Error::UnexpectedState);
}
match prefix {
Some(prefix) => self.output.write_fmt(format_args!("<{prefix}:{name}"))?,
None => match ns {
Some(ns) => self
.output
.write_fmt(format_args!("<{name} xmlns=\"{ns}\""))?,
None => self.output.write_fmt(format_args!("<{name}"))?,
let prefix = match ns == self.default_ns {
true => {
self.output.write_fmt(format_args!("<{name}"))?;
None
}
// In the case of scalars, we can use the prefix instead of setting a
// default namespace (since there are no child elements that will
// expect the default namespace to be set).
false => match (scalar, self.prefixes.get(ns)) {
(false, _) | (true, None) => {
self.output
.write_fmt(format_args!("<{name} xmlns=\"{ns}\""))?;
None
}
(true, Some(&prefix)) => {
self.output.write_fmt(format_args!("<{prefix}:{name}"))?;
Some(prefix)
}
},
}
};
self.state = State::Attribute;
Ok(())
Ok(prefix)
}
pub fn write_attr<V: ToXml + ?Sized>(&mut self, name: &str, value: &V) -> Result<(), Error> {