Track xml:lang throughout parsing
This commit is contained in:
parent
31d7bbf622
commit
d9a21dd8c9
21 changed files with 446 additions and 88 deletions
|
|
@ -68,7 +68,7 @@ impl Field for ChildField {
|
|||
|
||||
let from_events = from_events_fn(element_ty.clone());
|
||||
|
||||
let matcher = quote! { #from_events(name, attrs) };
|
||||
let matcher = quote! { #from_events(name, attrs, ctx) };
|
||||
let builder = from_xml_builder_ty(element_ty.clone());
|
||||
|
||||
(
|
||||
|
|
@ -307,7 +307,7 @@ impl ExtractDef {
|
|||
)?;
|
||||
let from_xml_builder_ty = ty_from_ident(from_xml_builder_ty_ident.clone()).into();
|
||||
|
||||
let matcher = quote! { #state_ty_ident::new(name, attrs).map(|x| #from_xml_builder_ty_ident(::core::option::Option::Some(x))) };
|
||||
let matcher = quote! { #state_ty_ident::new(name, attrs, ctx).map(|x| #from_xml_builder_ty_ident(::core::option::Option::Some(x))) };
|
||||
|
||||
let inner_ty = self.parts.to_single_or_tuple_ty();
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ impl Field for ElementField {
|
|||
if #field_access.is_some() {
|
||||
::core::result::Result::Err(::xso::error::FromEventsError::Mismatch { name, attrs })
|
||||
} else {
|
||||
#from_events(name, attrs)
|
||||
#from_events(name, attrs, ctx)
|
||||
}
|
||||
}),
|
||||
builder,
|
||||
|
|
|
|||
72
xso-proc/src/field/lang.rs
Normal file
72
xso-proc/src/field/lang.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) 2025 Jonas Schäfer <jonas@zombofant.net>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
//! This module concerns the processing of inherited `xml:lang` values.
|
||||
//!
|
||||
//! In particular, it provides the `#[xml(lang)]` implementation.
|
||||
|
||||
use proc_macro2::Span;
|
||||
use quote::quote;
|
||||
use syn::*;
|
||||
|
||||
use crate::error_message::ParentRef;
|
||||
use crate::scope::{AsItemsScope, FromEventsScope};
|
||||
use crate::types::{as_optional_xml_text_fn, option_ty, string_ty};
|
||||
|
||||
use super::{Field, FieldBuilderPart, FieldIteratorPart, FieldTempInit};
|
||||
|
||||
/// The field maps to a potentially inherited `xml:lang` value.
|
||||
pub(super) struct LangField;
|
||||
|
||||
impl Field for LangField {
|
||||
fn make_builder_part(
|
||||
&self,
|
||||
_scope: &FromEventsScope,
|
||||
_container_name: &ParentRef,
|
||||
_member: &Member,
|
||||
_ty: &Type,
|
||||
) -> Result<FieldBuilderPart> {
|
||||
let string_ty = string_ty(Span::call_site());
|
||||
let ty = option_ty(string_ty.clone());
|
||||
|
||||
Ok(FieldBuilderPart::Init {
|
||||
value: FieldTempInit {
|
||||
ty,
|
||||
init: quote! {
|
||||
ctx.language().map(#string_ty::from).into()
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn make_iterator_part(
|
||||
&self,
|
||||
_scope: &AsItemsScope,
|
||||
_container_name: &ParentRef,
|
||||
bound_name: &Ident,
|
||||
_member: &Member,
|
||||
ty: &Type,
|
||||
) -> Result<FieldIteratorPart> {
|
||||
let as_optional_xml_text = as_optional_xml_text_fn(ty.clone());
|
||||
|
||||
Ok(FieldIteratorPart::Header {
|
||||
generator: quote! {
|
||||
#as_optional_xml_text(#bound_name)?.map(|#bound_name|
|
||||
::xso::Item::Attribute(
|
||||
::xso::exports::rxml::Namespace::XML,
|
||||
// SAFETY: `lang` is a known-good NcName
|
||||
unsafe {
|
||||
::xso::exports::alloc::borrow::Cow::Borrowed(
|
||||
::xso::exports::rxml::NcNameStr::from_str_unchecked("lang"),
|
||||
)
|
||||
},
|
||||
#bound_name,
|
||||
)
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ mod child;
|
|||
#[cfg(feature = "minidom")]
|
||||
mod element;
|
||||
mod flag;
|
||||
mod lang;
|
||||
mod text;
|
||||
|
||||
use self::attribute::AttributeField;
|
||||
|
|
@ -28,6 +29,7 @@ use self::child::{ChildField, ExtractDef};
|
|||
#[cfg(feature = "minidom")]
|
||||
use self::element::ElementField;
|
||||
use self::flag::FlagField;
|
||||
use self::lang::LangField;
|
||||
use self::text::TextField;
|
||||
|
||||
/// Code slices necessary for declaring and initializing a temporary variable
|
||||
|
|
@ -444,6 +446,8 @@ fn new_field(
|
|||
xml_name,
|
||||
}))
|
||||
}
|
||||
|
||||
XmlFieldMeta::Language { span: _ } => Ok(Box::new(LangField)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue