xso_proc/common.rs
1// Copyright (c) 2024 Jonas Schäfer <jonas@zombofant.net>
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7//! Definitions common to both enums and structs
8
9use proc_macro2::TokenStream;
10use quote::{quote, ToTokens};
11use syn::*;
12
13/// Template which renders to a `xso::fromxml::XmlNameMatcher` value.
14pub(crate) enum XmlNameMatcher {
15 /// Renders as `xso::fromxml::XmlNameMatcher::Any`.
16 #[allow(dead_code)] // We keep it for completeness.
17 Any,
18
19 /// Renders as `xso::fromxml::XmlNameMatcher::InNamespace(#0)`.
20 InNamespace(TokenStream),
21
22 /// Renders as `xso::fromxml::XmlNameMatcher::Specific(#0, #1)`.
23 Specific(TokenStream, TokenStream),
24
25 /// Renders as `#0`.
26 ///
27 /// This is an escape hatch for more complicated constructs, e.g. when
28 /// a superset of multiple matchers is required.
29 Custom(TokenStream),
30}
31
32impl ToTokens for XmlNameMatcher {
33 fn to_tokens(&self, tokens: &mut TokenStream) {
34 match self {
35 Self::Any => tokens.extend(quote! {
36 ::xso::fromxml::XmlNameMatcher::<'static>::Any
37 }),
38 Self::InNamespace(ref namespace) => tokens.extend(quote! {
39 ::xso::fromxml::XmlNameMatcher::<'static>::InNamespace(#namespace)
40 }),
41 Self::Specific(ref namespace, ref name) => tokens.extend(quote! {
42 ::xso::fromxml::XmlNameMatcher::<'static>::Specific(#namespace, #name)
43 }),
44 Self::Custom(ref stream) => tokens.extend(stream.clone()),
45 }
46 }
47}
48
49/// Parts necessary to construct a `::xso::FromXml` implementation.
50pub(crate) struct FromXmlParts {
51 /// Additional items necessary for the implementation.
52 pub(crate) defs: TokenStream,
53
54 /// The body of the `::xso::FromXml::from_xml` function.
55 pub(crate) from_events_body: TokenStream,
56
57 /// The name of the type which is the `::xso::FromXml::Builder`.
58 pub(crate) builder_ty_ident: Ident,
59
60 /// The `XmlNameMatcher` to pre-select elements for this implementation.
61 pub(crate) name_matcher: XmlNameMatcher,
62}
63
64/// Parts necessary to construct a `::xso::AsXml` implementation.
65pub(crate) struct AsXmlParts {
66 /// Additional items necessary for the implementation.
67 pub(crate) defs: TokenStream,
68
69 /// The body of the `::xso::AsXml::as_xml_iter` function.
70 pub(crate) as_xml_iter_body: TokenStream,
71
72 /// The type which is the `::xso::AsXml::ItemIter`.
73 pub(crate) item_iter_ty: Type,
74
75 /// The lifetime name used in `item_iter_ty`.
76 pub(crate) item_iter_ty_lifetime: Lifetime,
77}
78
79/// Trait describing the definition of the XML (de-)serialisation for an item
80/// (enum or struct).
81pub(crate) trait ItemDef {
82 /// Construct the parts necessary for the caller to build an
83 /// `xso::FromXml` implementation for the item.
84 fn make_from_events_builder(
85 &self,
86 vis: &Visibility,
87 name_ident: &Ident,
88 attrs_ident: &Ident,
89 ) -> Result<FromXmlParts>;
90
91 /// Construct the parts necessary for the caller to build an `xso::AsXml`
92 /// implementation for the item.
93 fn make_as_xml_iter(&self, vis: &Visibility) -> Result<AsXmlParts>;
94
95 /// Return true iff the user requested debug output.
96 fn debug(&self) -> bool;
97}