xml: Fix dumb bug where default value would be evaluated and panic even when not needed

This commit is contained in:
Lennart
2025-05-02 20:38:27 +02:00
parent 6dc948ee78
commit 630a4600c2
4 changed files with 28 additions and 10 deletions

View File

@@ -1,7 +1,7 @@
[package] [package]
name = "xml_derive" name = "xml_derive"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2024"
[lib] [lib]
proc-macro = true proc-macro = true

View File

@@ -1,9 +1,9 @@
use std::collections::HashMap; use std::collections::HashMap;
use darling::{util::Flag, FromDeriveInput, FromField, FromMeta, FromVariant}; use darling::{FromDeriveInput, FromField, FromMeta, FromVariant, util::Flag};
use syn::LitByteStr; use syn::LitByteStr;
#[derive(Default, FromMeta, Clone)] #[derive(Debug, Default, FromMeta, Clone)]
pub struct TagAttrs { pub struct TagAttrs {
pub rename: Option<LitByteStr>, pub rename: Option<LitByteStr>,
pub ns: Option<syn::Path>, pub ns: Option<syn::Path>,
@@ -35,7 +35,7 @@ pub struct StructAttrs {
pub allow_invalid: Flag, pub allow_invalid: Flag,
} }
#[derive(Default, FromMeta, PartialEq)] #[derive(Debug, Default, FromMeta, PartialEq)]
pub enum FieldType { pub enum FieldType {
#[default] #[default]
Tag, Tag,
@@ -46,7 +46,7 @@ pub enum FieldType {
Namespace, Namespace,
} }
#[derive(Default, FromField)] #[derive(Debug, Default, FromField)]
#[darling(attributes(xml))] #[darling(attributes(xml))]
pub struct FieldAttrs { pub struct FieldAttrs {
#[darling(flatten)] #[darling(flatten)]

View File

@@ -4,8 +4,8 @@ use super::{
}; };
use darling::FromField; use darling::FromField;
use heck::ToKebabCase; use heck::ToKebabCase;
use quote::quote;
use quote::ToTokens; use quote::ToTokens;
use quote::quote;
use syn::spanned::Spanned; use syn::spanned::Spanned;
fn wrap_option_if_no_default( fn wrap_option_if_no_default(
@@ -36,13 +36,15 @@ impl Field {
/// Field name in XML /// Field name in XML
pub fn xml_name(&self) -> syn::LitByteStr { pub fn xml_name(&self) -> syn::LitByteStr {
self.attrs.common.rename.to_owned().unwrap_or({ if let Some(rename) = self.attrs.common.rename.to_owned() {
rename
} else {
let ident = self let ident = self
.field_ident() .field_ident()
.as_ref() .as_ref()
.expect("unnamed tag fields need a rename attribute"); .expect("unnamed tag fields need a rename attribute");
syn::LitByteStr::new(ident.to_string().to_kebab_case().as_bytes(), ident.span()) syn::LitByteStr::new(ident.to_string().to_kebab_case().as_bytes(), ident.span())
}) }
} }
/// Field identifier /// Field identifier

View File

@@ -3,8 +3,8 @@ use std::{
collections::HashMap, collections::HashMap,
}; };
use quick_xml::name::Namespace;
use quick_xml::Writer; use quick_xml::Writer;
use quick_xml::name::Namespace;
use rustical_xml::{XmlDocument, XmlRootTag, XmlSerialize, XmlSerializeRoot}; use rustical_xml::{XmlDocument, XmlRootTag, XmlSerialize, XmlSerializeRoot};
use xml_derive::XmlDeserialize; use xml_derive::XmlDeserialize;
@@ -196,7 +196,6 @@ fn test_struct_tag_list() {
#[test] #[test]
fn test_struct_ns() { fn test_struct_ns() {
// const NS: Namespace = Namespace(b"TEST", quick_xml::name::Namespace(b"NS:TEST:"));
const NS: Namespace = quick_xml::name::Namespace(b"NS:TEST:"); const NS: Namespace = quick_xml::name::Namespace(b"NS:TEST:");
#[derive(Debug, XmlRootTag, XmlSerialize)] #[derive(Debug, XmlRootTag, XmlSerialize)]
@@ -239,3 +238,20 @@ fn test_struct_tuple() {
let out = String::from_utf8(buf).unwrap(); let out = String::from_utf8(buf).unwrap();
dbg!(out); dbg!(out);
} }
#[test]
fn test_tuple_struct() {
const NS: Namespace = quick_xml::name::Namespace(b"NS:TEST:");
#[derive(Debug, XmlRootTag, XmlSerialize)]
#[xml(root = b"document")]
struct Document(#[xml(ns = "NS", rename = b"okay")] String);
let mut buf = Vec::new();
let mut writer = quick_xml::Writer::new(&mut buf);
Document("hello!".to_string())
.serialize_root(&mut writer)
.unwrap();
let out = String::from_utf8(buf).unwrap();
dbg!(out);
}