use xmlity::de::DeserializeContext;
use crate::define_deserialize_test;
use std::str::FromStr;
use xmlity::{Deserialize, Prefix};
use xmlity::{XmlNamespace, XmlNamespaceBuf};
#[derive(Debug, PartialEq)]
pub struct InternalReference(pub XmlNamespaceBuf);
impl<'de> Deserialize<'de> for InternalReference {
fn deserialize<D: xmlity::Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
struct __Visitor;
impl<'de> xmlity::de::Visitor<'de> for __Visitor {
type Value = InternalReference;
fn visit_text<E, V>(self, value: V) -> Result<Self::Value, E>
where
E: xmlity::de::Error,
V: xmlity::de::XmlText<'de>,
{
let prefix = Prefix::new(value.as_str()).map_err(|e| {
E::custom(format!("Internal reference is not valid prefix: {e:?}"))
})?;
let namespace = value
.context()
.resolve_prefix(prefix)
.ok_or_else(|| E::custom(format!("Prefix {prefix:?} is not defined")))?
.to_owned();
Ok(InternalReference(namespace))
}
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("Internal reference")
}
}
reader.deserialize_any(__Visitor)
}
}
#[derive(Debug, PartialEq, Deserialize)]
#[xelement(
name = "prefix",
namespace = "http://my.namespace.example.com/this/is/a/namespace",
preferred_prefix = "myns"
)]
pub struct PrefixElement(InternalReference);
define_deserialize_test!(
element_with_internal_reference,
[(PrefixElement(
InternalReference(XmlNamespaceBuf::from_str("http://my.namespace.example.com/this/is/a/namespace").unwrap())
), "<myns:prefix xmlns:myns=\"http://my.namespace.example.com/this/is/a/namespace\">myns</myns:prefix>")]
);
#[derive(Debug, PartialEq)]
pub struct DefaultNamespace(pub Option<XmlNamespaceBuf>);
impl<'de> Deserialize<'de> for DefaultNamespace {
fn deserialize<D: xmlity::Deserializer<'de>>(reader: D) -> Result<Self, D::Error> {
struct __Visitor;
impl<'de> xmlity::de::Visitor<'de> for __Visitor {
type Value = DefaultNamespace;
fn visit_text<E, V>(self, value: V) -> Result<Self::Value, E>
where
E: xmlity::de::Error,
V: xmlity::de::XmlText<'de>,
{
let namespace = value
.context()
.default_namespace()
.map(XmlNamespace::to_owned);
Ok(DefaultNamespace(namespace))
}
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("Internal reference")
}
}
reader.deserialize_any(__Visitor)
}
}
#[derive(Debug, PartialEq, Deserialize)]
#[xelement(
name = "default",
namespace = "http://my.namespace.example.com/this/is/a/namespace"
)]
pub struct NamespaceElement(DefaultNamespace);
define_deserialize_test!(
element_with_default_namespace,
[(
NamespaceElement(DefaultNamespace(Some(
XmlNamespaceBuf::from_str("http://my.namespace.example.com/this/is/a/namespace")
.unwrap()
))),
"<default xmlns=\"http://my.namespace.example.com/this/is/a/namespace\">Abcde</default>"
)]
);