xso: fix no_std support

Jonas SchΓ€fer created

This reverts the Revert in 6ec275d3 which had to be done in order to
un-break usage of xso in std crates.

Change summary

xso-proc/src/enums.rs           |  2 +-
xso-proc/src/field/attribute.rs |  2 +-
xso-proc/src/field/child.rs     |  2 +-
xso-proc/src/field/flag.rs      |  2 +-
xso-proc/src/field/text.rs      |  2 +-
xso-proc/src/structs.rs         |  2 +-
xso-proc/src/types.rs           | 22 +++++++++++++++++++---
xso/ChangeLog                   |  1 +
xso/src/lib.rs                  | 16 ++++++++++++++++
9 files changed, 42 insertions(+), 9 deletions(-)

Detailed changes

xso-proc/src/enums.rs πŸ”—

@@ -140,7 +140,7 @@ impl NameVariant {
                 quote! {
                     let name = (
                         ::xso::exports::rxml::Namespace::from(#xml_namespace),
-                        ::std::borrow::Cow::Borrowed(#xml_name),
+                        ::xso::exports::alloc::borrow::Cow::Borrowed(#xml_name),
                     );
                     #init
                 }

xso-proc/src/field/attribute.rs πŸ”—

@@ -128,7 +128,7 @@ impl Field for AttributeField {
             generator: quote! {
                 #generator.map(|#bound_name| ::xso::Item::Attribute(
                     #xml_namespace,
-                    ::std::borrow::Cow::Borrowed(#xml_name),
+                    ::xso::exports::alloc::borrow::Cow::Borrowed(#xml_name),
                     #bound_name,
                 ));
             },

xso-proc/src/field/child.rs πŸ”—

@@ -423,7 +423,7 @@ impl ExtractDef {
                 quote! {
                     let name = (
                         ::xso::exports::rxml::Namespace::from(#xml_namespace),
-                        ::std::borrow::Cow::Borrowed(#xml_name),
+                        ::xso::exports::alloc::borrow::Cow::Borrowed(#xml_name),
                     );
                     #init
                 }

xso-proc/src/field/flag.rs πŸ”—

@@ -125,7 +125,7 @@ impl Field for FlagField {
                         2 => ::core::result::Result::Ok(::core::option::Option::Some(
                             ::xso::Item::ElementHeadStart(
                                 ::xso::exports::rxml::Namespace::from(#xml_namespace),
-                                ::std::borrow::Cow::Borrowed(#xml_name),
+                                ::xso::exports::alloc::borrow::Cow::Borrowed(#xml_name),
                             )
                         )),
                         _ => unreachable!(),

xso-proc/src/field/text.rs πŸ”—

@@ -51,7 +51,7 @@ impl Field for TextField {
 
         Ok(FieldBuilderPart::Text {
             value: FieldTempInit {
-                init: quote! { ::std::string::String::new() },
+                init: quote! { ::xso::exports::alloc::string::String::new() },
                 ty: string_ty(Span::call_site()),
             },
             collect: quote! {

xso-proc/src/structs.rs πŸ”—

@@ -294,7 +294,7 @@ impl StructInner {
                     quote! {
                         let name = (
                             ::xso::exports::rxml::Namespace::from(#xml_namespace),
-                            ::std::borrow::Cow::Borrowed(#xml_name),
+                            ::xso::exports::alloc::borrow::Cow::Borrowed(#xml_name),
                         );
                         #init
                     }

xso-proc/src/types.rs πŸ”—

@@ -84,7 +84,15 @@ pub(crate) fn cow_ty(ty: Type, lifetime: Lifetime) -> Type {
             }),
             segments: [
                 PathSegment {
-                    ident: Ident::new("std", span),
+                    ident: Ident::new("xso", span),
+                    arguments: PathArguments::None,
+                },
+                PathSegment {
+                    ident: Ident::new("exports", span),
+                    arguments: PathArguments::None,
+                },
+                PathSegment {
+                    ident: Ident::new("alloc", span),
                     arguments: PathArguments::None,
                 },
                 PathSegment {
@@ -233,7 +241,7 @@ pub(crate) fn default_fn(of_ty: Type) -> Expr {
     })
 }
 
-/// Construct a [`syn::Type`] referring to `::std::string::String`.
+/// Construct a [`syn::Type`] referring to `::alloc::string::String`.
 pub(crate) fn string_ty(span: Span) -> Type {
     Type::Path(TypePath {
         qself: None,
@@ -243,7 +251,15 @@ pub(crate) fn string_ty(span: Span) -> Type {
             }),
             segments: [
                 PathSegment {
-                    ident: Ident::new("std", span),
+                    ident: Ident::new("xso", span),
+                    arguments: PathArguments::None,
+                },
+                PathSegment {
+                    ident: Ident::new("exports", span),
+                    arguments: PathArguments::None,
+                },
+                PathSegment {
+                    ident: Ident::new("alloc", span),
                     arguments: PathArguments::None,
                 },
                 PathSegment {

xso/ChangeLog πŸ”—

@@ -31,6 +31,7 @@ Version NEXT:
         the base64 crate (if the `base64` feature is enabled).
       - New `codec` field on `attribute` meta, to support decoding and
         encoding using any `TextCodec`.
+      - Support for `no_std` usage (the alloc crate is required, though).
 
 Version 0.1.2:
 2024-07-26 Jonas SchΓ€fer <jonas@zombofant.net>

xso/src/lib.rs πŸ”—

@@ -45,6 +45,22 @@ pub mod exports {
     pub use minidom;
     pub use rxml;
 
+    // These re-exports are necessary to support both std and no_std in code
+    // generated by the macros.
+    //
+    // If we attempted to use ::alloc directly from macros, std builds would
+    // not work because alloc is not generally present in builds using std.
+    // If we used ::std, no_std builds would obviously not work. By exporting
+    // std as alloc in std builds, we can safely use the alloc types from
+    // there.
+    //
+    // Obviously, we have to be careful in xso-proc to not refer to types
+    // which are not in alloc.
+    #[cfg(not(feature = "std"))]
+    pub extern crate alloc;
+    #[cfg(feature = "std")]
+    pub extern crate std as alloc;
+
     /// The built-in `bool` type.
     ///
     /// This is re-exported for use by macros in cases where we cannot rely on