xso-proc: introduce trait for StructDef

Jonas Schäfer created

Can you see it coming?

Change summary

xso-proc/src/common.rs  | 57 +++++++++++++++++++++++++++++++++++++++++++
xso-proc/src/lib.rs     |  7 +++-
xso-proc/src/structs.rs | 38 +++++-----------------------
3 files changed, 69 insertions(+), 33 deletions(-)

Detailed changes

xso-proc/src/common.rs 🔗

@@ -0,0 +1,57 @@
+// Copyright (c) 2024 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/.
+
+//! Definitions common to both enums and structs
+
+use proc_macro2::TokenStream;
+use syn::*;
+
+/// Parts necessary to construct a `::xso::FromXml` implementation.
+pub(crate) struct FromXmlParts {
+    /// Additional items necessary for the implementation.
+    pub(crate) defs: TokenStream,
+
+    /// The body of the `::xso::FromXml::from_xml` function.
+    pub(crate) from_events_body: TokenStream,
+
+    /// The name of the type which is the `::xso::FromXml::Builder`.
+    pub(crate) builder_ty_ident: Ident,
+}
+
+/// Parts necessary to construct a `::xso::AsXml` implementation.
+pub(crate) struct AsXmlParts {
+    /// Additional items necessary for the implementation.
+    pub(crate) defs: TokenStream,
+
+    /// The body of the `::xso::AsXml::as_xml_iter` function.
+    pub(crate) as_xml_iter_body: TokenStream,
+
+    /// The type which is the `::xso::AsXml::ItemIter`.
+    pub(crate) item_iter_ty: Type,
+
+    /// The lifetime name used in `item_iter_ty`.
+    pub(crate) item_iter_ty_lifetime: Lifetime,
+}
+
+/// Trait describing the definition of the XML (de-)serialisation for an item
+/// (enum or struct).
+pub(crate) trait ItemDef {
+    /// Construct the parts necessary for the caller to build an
+    /// `xso::FromXml` implementation for the item.
+    fn make_from_events_builder(
+        &self,
+        vis: &Visibility,
+        name_ident: &Ident,
+        attrs_ident: &Ident,
+    ) -> Result<FromXmlParts>;
+
+    /// Construct the parts necessary for the caller to build an `xso::AsXml`
+    /// implementation for the item.
+    fn make_as_xml_iter(&self, vis: &Visibility) -> Result<AsXmlParts>;
+
+    /// Return true iff the user requested debug output.
+    fn debug(&self) -> bool;
+}

xso-proc/src/lib.rs 🔗

@@ -25,6 +25,7 @@ use proc_macro2::{Span, TokenStream};
 use quote::quote;
 use syn::*;
 
+mod common;
 mod compound;
 mod error_message;
 mod field;
@@ -34,6 +35,8 @@ mod state;
 mod structs;
 mod types;
 
+use common::{AsXmlParts, FromXmlParts, ItemDef};
+
 /// Convert an [`syn::Item`] into the parts relevant for us.
 ///
 /// If the item is of an unsupported variant, an appropriate error is
@@ -57,7 +60,7 @@ fn from_xml_impl(input: Item) -> Result<TokenStream> {
     let name_ident = Ident::new("name", Span::call_site());
     let attrs_ident = Ident::new("attrs", Span::call_site());
 
-    let structs::FromXmlParts {
+    let FromXmlParts {
         defs,
         from_events_body,
         builder_ty_ident,
@@ -116,7 +119,7 @@ pub fn from_xml(input: RawTokenStream) -> RawTokenStream {
 fn as_xml_impl(input: Item) -> Result<TokenStream> {
     let (vis, ident, def) = parse_struct(input)?;
 
-    let structs::AsXmlParts {
+    let AsXmlParts {
         defs,
         as_xml_iter_body,
         item_iter_ty_lifetime,

xso-proc/src/structs.rs 🔗

@@ -6,40 +6,14 @@
 
 //! Handling of structs
 
-use proc_macro2::{Span, TokenStream};
+use proc_macro2::Span;
 use quote::quote;
 use syn::*;
 
+use crate::common::{AsXmlParts, FromXmlParts, ItemDef};
 use crate::compound::Compound;
 use crate::meta::{NameRef, NamespaceRef, XmlCompoundMeta};
 
-/// Parts necessary to construct a `::xso::FromXml` implementation.
-pub(crate) struct FromXmlParts {
-    /// Additional items necessary for the implementation.
-    pub(crate) defs: TokenStream,
-
-    /// The body of the `::xso::FromXml::from_xml` function.
-    pub(crate) from_events_body: TokenStream,
-
-    /// The name of the type which is the `::xso::FromXml::Builder`.
-    pub(crate) builder_ty_ident: Ident,
-}
-
-/// Parts necessary to construct a `::xso::AsXml` implementation.
-pub(crate) struct AsXmlParts {
-    /// Additional items necessary for the implementation.
-    pub(crate) defs: TokenStream,
-
-    /// The body of the `::xso::AsXml::as_xml_iter` function.
-    pub(crate) as_xml_iter_body: TokenStream,
-
-    /// The type which is the `::xso::AsXml::ItemIter`.
-    pub(crate) item_iter_ty: Type,
-
-    /// The lifetime name used in `item_iter_ty`.
-    pub(crate) item_iter_ty_lifetime: Lifetime,
-}
-
 /// Definition of a struct and how to parse it.
 pub(crate) struct StructDef {
     /// The XML namespace of the element to map the struct to.
@@ -95,8 +69,10 @@ impl StructDef {
             debug: meta.debug.is_set(),
         })
     }
+}
 
-    pub(crate) fn make_from_events_builder(
+impl ItemDef for StructDef {
+    fn make_from_events_builder(
         &self,
         vis: &Visibility,
         name_ident: &Ident,
@@ -149,7 +125,7 @@ impl StructDef {
         })
     }
 
-    pub(crate) fn make_as_xml_iter(&self, vis: &Visibility) -> Result<AsXmlParts> {
+    fn make_as_xml_iter(&self, vis: &Visibility) -> Result<AsXmlParts> {
         let xml_namespace = &self.namespace;
         let xml_name = &self.name;
 
@@ -223,7 +199,7 @@ impl StructDef {
         })
     }
 
-    pub(crate) fn debug(&self) -> bool {
+    fn debug(&self) -> bool {
         self.debug
     }
 }