1use proc_macro2::{Literal, TokenStream};
2use quote::quote;
3use xsd_parser_types::{misc::Namespace, xml::QName};
4
5use crate::pipeline::{
6 generator::{Context as GeneratorContext, Error, ValueGeneratorMode},
7 renderer::{Context as RendererContext, ValueRendererBox},
8};
9
10pub fn default(
13 ctx: &GeneratorContext<'_, '_>,
14 value: &str,
15 mode: ValueGeneratorMode,
16) -> Result<ValueRendererBox, Error> {
17 if mode == ValueGeneratorMode::Literal {
18 return Err(Error::InvalidDefaultValue {
19 ident: ctx.ident.clone(),
20 value: value.into(),
21 mode,
22 });
23 }
24
25 let name = QName::from_bytes(value.as_bytes().to_owned());
26 let ns = name
27 .prefix()
28 .and_then(|prefix| ctx.namespaces()?.get(prefix))
29 .map(|ns| Namespace::new(ns.to_vec()));
30
31 Ok(Box::new(
32 move |ctx: &RendererContext<'_, '_>| -> TokenStream {
33 let qname = ctx.resolve_ident_path("::xsd_parser_types::xml::QName");
34 let namespace = ctx.resolve_ident_path("::xsd_parser_types::misc::Namespace");
35
36 let ns = match &ns {
37 None => quote::quote!(None),
38 Some(x) if *x == Namespace::XS => quote::quote!(Some(#namespace::XS)),
39 Some(x) if *x == Namespace::XSI => quote::quote!(Some(#namespace::XSI)),
40 Some(x) if *x == Namespace::XML => quote::quote!(Some(#namespace::XML)),
41 Some(x) => {
42 let x = Literal::byte_string(x.as_ref());
43
44 quote::quote!(Some(#namespace::new_const(#x)))
45 }
46 };
47 let index = match name.index() {
48 Some(index) => quote::quote!(Some(#index)),
49 None => quote::quote!(None),
50 };
51 let raw = Literal::byte_string(name.as_bytes());
52
53 quote!(#qname::new_const(#raw, #index, #ns))
54 },
55 ))
56}