Skip to main content

specta_serde/
serde_attrs.rs

1//! Comprehensive serde attribute parsing and transformation system.
2//!
3//! This module provides functionality to parse serde attributes like `#[serde(rename = "...")]`,
4//! `#[serde(rename_all = "...")]`, and repr-related attributes, and apply them to DataType
5//! instances with separate handling for serialization and deserialization phases.
6
7use std::{borrow::Cow, fmt};
8
9use specta::{
10    datatype::{
11        DataType, Enum, Fields, RuntimeAttribute, RuntimeLiteral, RuntimeMeta, RuntimeNestedMeta,
12        RuntimeValue, Struct, Tuple,
13    },
14    internal,
15};
16
17use crate::{Error, inflection::RenameRule, repr::EnumRepr};
18
19/// Specifies whether to apply serde transformations for serialization or deserialization
20#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
21pub enum SerdeMode {
22    /// Apply transformations for serialization (Rust -> JSON/etc)
23    Serialize,
24    /// Apply transformations for deserialization (JSON/etc -> Rust)
25    Deserialize,
26    /// Apply transformations for both serialization and deserialization
27    ///
28    /// This mode uses common transformations (like `rename`, `rename_all`, `skip`)
29    /// but skips mode-specific attributes (like `rename_serialize`, `skip_serializing`).
30    /// A field/type is only skipped if it's skipped in both modes.
31    #[default]
32    Both,
33}
34
35impl fmt::Display for SerdeMode {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        write!(f, "{self:?}")
38    }
39}
40
41/// Contains parsed serde attributes for a type
42#[derive(Debug, Clone, Default)]
43pub struct SerdeAttributes {
44    /// Direct rename specified by #[serde(rename = "name")]
45    pub rename: Option<String>,
46    /// Separate names for serialization and deserialization
47    pub rename_serialize: Option<String>,
48    pub rename_deserialize: Option<String>,
49    /// Rename all fields/variants according to #[serde(rename_all = "case")]
50    pub rename_all: Option<RenameRule>,
51    /// Separate rename_all for serialization and deserialization
52    pub rename_all_serialize: Option<RenameRule>,
53    pub rename_all_deserialize: Option<RenameRule>,
54    /// Rename all fields in enum variants according to #[serde(rename_all_fields = "case")]
55    pub rename_all_fields: Option<RenameRule>,
56    /// Separate rename_all_fields for serialization and deserialization
57    pub rename_all_fields_serialize: Option<RenameRule>,
58    pub rename_all_fields_deserialize: Option<RenameRule>,
59    /// Skip serialization with #[serde(skip_serializing)]
60    pub skip_serializing: bool,
61    /// Skip deserialization with #[serde(skip_deserializing)]
62    pub skip_deserializing: bool,
63    /// Skip both serialization and deserialization with #[serde(skip)]
64    pub skip: bool,
65    /// Flatten this field/variant with #[serde(flatten)]
66    pub flatten: bool,
67    /// Default value with #[serde(default)]
68    pub default: bool,
69    /// Default value with custom function #[serde(default = "path")]
70    pub default_with: Option<String>,
71    /// Transparent container with #[serde(transparent)]
72    pub transparent: bool,
73    /// Deny unknown fields #[serde(deny_unknown_fields)]
74    pub deny_unknown_fields: bool,
75    /// Enum representation
76    pub repr: Option<EnumRepr>,
77    /// Tag for internally tagged enums
78    pub tag: Option<String>,
79    /// Content field for adjacently tagged enums
80    pub content: Option<String>,
81    /// Untagged enum
82    pub untagged: bool,
83    /// Remote type definition #[serde(remote = "...")]
84    pub remote: Option<String>,
85    /// Convert from another type #[serde(from = "...")]
86    pub from: Option<String>,
87    /// Try convert from another type #[serde(try_from = "...")]
88    pub try_from: Option<String>,
89    /// Convert into another type #[serde(into = "...")]
90    pub into: Option<String>,
91    /// Deserialize unknown variants to this variant #[serde(other)]
92    pub other: bool,
93    /// Aliases for deserialization #[serde(alias = "name")]
94    pub alias: Vec<String>,
95    /// Serialize with custom function #[serde(serialize_with = "path")]
96    pub serialize_with: Option<String>,
97    /// Deserialize with custom function #[serde(deserialize_with = "path")]
98    pub deserialize_with: Option<String>,
99    /// Combined serialize/deserialize with module #[serde(with = "module")]
100    pub with: Option<String>,
101}
102
103/// Contains parsed serde attributes for a field
104#[derive(Debug, Clone, Default)]
105pub struct SerdeFieldAttributes {
106    /// Field-specific attributes
107    pub base: SerdeAttributes,
108    /// Field alias for deserialization #[serde(alias = "name")]
109    #[allow(dead_code)]
110    pub alias: Vec<String>,
111    /// Serialize with custom function #[serde(serialize_with = "path")]
112    pub serialize_with: Option<String>,
113    /// Deserialize with custom function #[serde(deserialize_with = "path")]
114    pub deserialize_with: Option<String>,
115    /// Combined serialize/deserialize with module #[serde(with = "module")]
116    pub with: Option<String>,
117    /// Skip serializing if condition is true #[serde(skip_serializing_if = "path")]
118    pub skip_serializing_if: Option<String>,
119}
120
121/// Apply serde transformations to a DataType for the specified mode
122pub fn apply_serde_transformations(
123    datatype: &DataType,
124    mode: SerdeMode,
125) -> Result<DataType, Error> {
126    let mut transformer = SerdeTransformer::new(mode, None);
127    transformer.transform_datatype(datatype)
128}
129
130/// Apply serde transformations to a DataType with a type name (for struct tagging)
131pub fn apply_serde_transformations_with_name(
132    datatype: &DataType,
133    type_name: &str,
134    mode: SerdeMode,
135) -> Result<DataType, Error> {
136    let mut transformer = SerdeTransformer::new(mode, Some(type_name.to_string()));
137    transformer.transform_datatype(datatype)
138}
139
140/// Internal transformer that applies serde attributes to DataType instances
141struct SerdeTransformer {
142    mode: SerdeMode,
143    type_name: Option<String>,
144}
145
146impl SerdeTransformer {
147    fn new(mode: SerdeMode, type_name: Option<String>) -> Self {
148        Self { mode, type_name }
149    }
150
151    /// Transform a DataType with serde attributes applied
152    fn transform_datatype(&mut self, datatype: &DataType) -> Result<DataType, Error> {
153        match datatype {
154            DataType::Primitive(p) => Ok(DataType::Primitive(p.clone())),
155            DataType::List(list) => {
156                let transformed_inner = self.transform_datatype(list.ty())?;
157                let mut transformed_list = list.clone();
158                transformed_list.set_ty(transformed_inner);
159                Ok(DataType::List(transformed_list))
160            }
161            DataType::Map(map) => {
162                let transformed_key = self.transform_datatype(map.key_ty())?;
163                let transformed_value = self.transform_datatype(map.value_ty())?;
164                Ok(DataType::Map(specta::datatype::Map::new(
165                    transformed_key,
166                    transformed_value,
167                )))
168            }
169            DataType::Nullable(inner) => {
170                let transformed_inner = self.transform_datatype(inner)?;
171                Ok(DataType::Nullable(Box::new(transformed_inner)))
172            }
173            DataType::Struct(s) => self.transform_struct(s),
174            DataType::Enum(e) => self.transform_enum(e),
175            DataType::Tuple(t) => self.transform_tuple(t),
176            DataType::Reference(r) => Ok(DataType::Reference(r.clone())),
177            DataType::Generic(g) => Ok(DataType::Generic(g.clone())),
178        }
179    }
180
181    /// Transform a Struct with serde attributes
182    fn transform_struct(&mut self, struct_type: &Struct) -> Result<DataType, Error> {
183        let attrs = parse_serde_attributes(struct_type.attributes())?;
184
185        // Handle transparent structs
186        if attrs.transparent {
187            return self.handle_transparent_struct(struct_type);
188        }
189
190        // Handle skip based on mode
191        if self.should_skip_type(&attrs) {
192            // Return a unit type or some representation of skipped field
193            return Ok(DataType::Tuple(Tuple::new(vec![])));
194        }
195
196        let mut transformed_fields = self.transform_fields(struct_type.fields(), &attrs)?;
197
198        // If the struct has a tag attribute (for struct tagging), add the tag field
199        if let Some(tag_name) = &attrs.tag {
200            transformed_fields =
201                self.add_struct_tag_field(tag_name, struct_type, transformed_fields)?;
202        }
203
204        let mut new_struct = Struct::unit();
205        new_struct.set_fields(transformed_fields);
206        new_struct.set_attributes(struct_type.attributes().clone());
207
208        Ok(DataType::Struct(new_struct))
209    }
210
211    /// Transform an Enum with serde attributes
212    fn transform_enum(&mut self, enum_type: &Enum) -> Result<DataType, Error> {
213        let attrs = parse_serde_attributes(enum_type.attributes())?;
214
215        // Handle skip based on mode
216        if self.should_skip_type(&attrs) {
217            return Ok(DataType::Tuple(Tuple::new(vec![])));
218        }
219
220        // Determine enum representation
221        let repr = attrs.repr.clone().unwrap_or(EnumRepr::External);
222
223        // Handle string enums specially, but only if they're not internally/adjacently tagged
224        // Internally/adjacently tagged enums need to go through the normal tagging transformation
225        // to add tag fields to unit variants
226        if enum_type.is_string_enum()
227            && attrs.rename_all.is_some()
228            && !matches!(repr, EnumRepr::Internal { .. } | EnumRepr::Adjacent { .. })
229        {
230            return self.transform_string_enum(enum_type, &attrs);
231        }
232
233        let mut transformed_variants = Vec::new();
234
235        for (variant_name, variant) in enum_type.variants() {
236            let variant_attrs = parse_serde_attributes(variant.attributes())?;
237
238            if variant.skip() || self.should_skip_type(&variant_attrs) {
239                continue;
240            }
241
242            let transformed_name = self.apply_rename_rule(
243                variant_name,
244                attrs.rename_all,
245                &variant_attrs.rename,
246                &variant_attrs,
247                true, // is_variant
248            )?;
249
250            // For enum variant fields, use rename_all_fields instead of rename_all
251            let mut variant_field_attrs = attrs.clone();
252            // Apply rename_all_fields to variant fields based on mode
253            match self.mode {
254                SerdeMode::Serialize => {
255                    if let Some(rule) = attrs
256                        .rename_all_fields_serialize
257                        .or(attrs.rename_all_fields)
258                    {
259                        variant_field_attrs.rename_all = Some(rule);
260                        variant_field_attrs.rename_all_serialize = Some(rule);
261                    }
262                }
263                SerdeMode::Deserialize => {
264                    if let Some(rule) = attrs
265                        .rename_all_fields_deserialize
266                        .or(attrs.rename_all_fields)
267                    {
268                        variant_field_attrs.rename_all = Some(rule);
269                        variant_field_attrs.rename_all_deserialize = Some(rule);
270                    }
271                }
272                SerdeMode::Both => {
273                    // For Both mode, use rename_all_fields if available
274                    if let Some(rule) = attrs.rename_all_fields {
275                        variant_field_attrs.rename_all = Some(rule);
276                    }
277                }
278            }
279
280            let transformed_fields =
281                self.transform_fields(variant.fields(), &variant_field_attrs)?;
282
283            // Apply enum tagging transformation based on representation
284            let final_fields =
285                self.apply_enum_tagging(&repr, &transformed_name, transformed_fields)?;
286
287            let mut new_variant = variant.clone();
288            new_variant.set_fields(final_fields);
289
290            transformed_variants.push((transformed_name, new_variant));
291        }
292
293        if !enum_type.variants().is_empty() && transformed_variants.is_empty() {
294            return Err(Error::InvalidUsageOfSkip);
295        }
296
297        let mut new_enum = Enum::new();
298        *new_enum.variants_mut() = transformed_variants;
299        *new_enum.attributes_mut() = enum_type.attributes().clone();
300
301        Ok(DataType::Enum(new_enum))
302    }
303
304    /// Transform a string enum (unit-only enum) with rename_all support
305    fn transform_string_enum(
306        &mut self,
307        enum_type: &Enum,
308        attrs: &SerdeAttributes,
309    ) -> Result<DataType, Error> {
310        let mut transformed_variants = Vec::new();
311
312        for (variant_name, variant) in enum_type.variants() {
313            if !matches!(variant.fields(), Fields::Unit) {
314                return Err(Error::InvalidUsageOfSkip); // Not a string enum
315            }
316
317            let variant_attrs = parse_serde_attributes(variant.attributes())?;
318            if self.should_skip_type(&variant_attrs) {
319                continue;
320            }
321
322            let transformed_name = self.apply_rename_rule(
323                variant_name,
324                attrs.rename_all,
325                &variant_attrs.rename,
326                &variant_attrs,
327                true,
328            )?;
329
330            transformed_variants.push((transformed_name, variant.clone()));
331        }
332
333        // Create enum with String representation
334        let mut new_enum = Enum::new();
335        *new_enum.variants_mut() = transformed_variants;
336        *new_enum.attributes_mut() = enum_type.attributes().clone();
337
338        Ok(DataType::Enum(new_enum))
339    }
340
341    /// Transform a Tuple with serde attributes
342    fn transform_tuple(&mut self, tuple: &Tuple) -> Result<DataType, Error> {
343        let mut transformed_elements = Vec::new();
344
345        for element in tuple.elements() {
346            let transformed = self.transform_datatype(element)?;
347            transformed_elements.push(transformed);
348        }
349
350        Ok(DataType::Tuple(Tuple::new(transformed_elements)))
351    }
352
353    /// Transform Fields with serde attributes applied
354    fn transform_fields(
355        &mut self,
356        fields: &Fields,
357        parent_attrs: &SerdeAttributes,
358    ) -> Result<Fields, Error> {
359        match fields {
360            Fields::Unit => Ok(Fields::Unit),
361            Fields::Unnamed(unnamed) => {
362                let mut transformed_fields = Vec::new();
363
364                for (idx, field) in unnamed.fields().iter().enumerate() {
365                    let field_attrs = parse_field_serde_attributes(field.attributes())?;
366
367                    if self.should_skip_field(&field_attrs) {
368                        let new_field = internal::construct::field(
369                            field.optional(),
370                            field.deprecated().cloned(),
371                            field.docs().clone(),
372                            field.inline(),
373                            field.attributes().clone(),
374                            None,
375                        );
376                        transformed_fields.push((idx, new_field));
377                        continue;
378                    }
379
380                    let new_field = match field.ty().cloned() {
381                        Some(field_ty) => {
382                            let transformed_ty = self.transform_datatype(&field_ty)?;
383                            let mut new_field = field.clone();
384                            new_field.set_ty(transformed_ty);
385                            new_field
386                        }
387                        // Keep previous behavior for `#[specta(skip)]` fields that were
388                        // lowered to `ty = None` by the macro.
389                        None => continue,
390                    };
391
392                    transformed_fields.push((idx, new_field));
393                }
394
395                Ok(internal::construct::fields_unnamed(
396                    transformed_fields.into_iter().map(|(_, f)| f).collect(),
397                    vec![],
398                ))
399            }
400            Fields::Named(named) => {
401                let mut transformed_fields = Vec::new();
402
403                for (field_name, field) in named.fields() {
404                    // Parse field-specific serde attributes from stored runtime attributes
405                    let field_attrs = parse_field_serde_attributes(field.attributes())?;
406
407                    if self.should_skip_field(&field_attrs) {
408                        continue;
409                    }
410
411                    let transformed_name = self.apply_rename_rule(
412                        field_name,
413                        parent_attrs.rename_all,
414                        &field_attrs.base.rename,
415                        &field_attrs.base,
416                        false, // is_variant
417                    )?;
418
419                    if let Some(field_ty) = field.ty() {
420                        let transformed_ty = self.transform_datatype(field_ty)?;
421                        let mut new_field = field.clone();
422                        new_field.set_ty(transformed_ty);
423
424                        // Set optional flag based on serde attributes
425                        // This matches the behavior that was previously in the macro
426                        if field_attrs.skip_serializing_if.is_some() || field_attrs.base.default {
427                            new_field.set_optional(true);
428                        }
429
430                        transformed_fields.push((transformed_name, new_field));
431                    }
432                }
433
434                Ok(internal::construct::fields_named(
435                    transformed_fields,
436                    vec![],
437                ))
438            }
439        }
440    }
441
442    /// Handle transparent structs
443    fn handle_transparent_struct(&mut self, struct_type: &Struct) -> Result<DataType, Error> {
444        use specta::datatype::{skip_fields, skip_fields_named};
445
446        match struct_type.fields() {
447            Fields::Unnamed(unnamed) => {
448                // Collect non-skipped fields
449                let non_skipped: Vec<_> = skip_fields(unnamed.fields()).collect();
450
451                if non_skipped.len() == 1 {
452                    self.transform_datatype(non_skipped[0].1)
453                } else {
454                    Err(Error::InvalidUsageOfSkip)
455                }
456            }
457            Fields::Named(named) => {
458                // Collect non-skipped fields
459                let non_skipped: Vec<_> = skip_fields_named(named.fields()).collect();
460
461                if non_skipped.len() == 1 {
462                    self.transform_datatype(non_skipped[0].1.1)
463                } else {
464                    Err(Error::InvalidUsageOfSkip)
465                }
466            }
467            _ => Err(Error::InvalidUsageOfSkip), // Invalid transparent usage
468        }
469    }
470
471    /// Check if a type should be skipped based on the current mode
472    fn should_skip_type(&self, attrs: &SerdeAttributes) -> bool {
473        if attrs.skip {
474            return true;
475        }
476
477        match self.mode {
478            SerdeMode::Serialize => attrs.skip_serializing,
479            SerdeMode::Deserialize => attrs.skip_deserializing,
480            // For Both mode, only skip if skipped in both directions
481            SerdeMode::Both => attrs.skip_serializing && attrs.skip_deserializing,
482        }
483    }
484
485    /// Check if a field should be skipped based on the current mode
486    fn should_skip_field(&self, attrs: &SerdeFieldAttributes) -> bool {
487        self.should_skip_type(&attrs.base)
488    }
489
490    /// Apply rename rules to a field or variant name
491    fn apply_rename_rule(
492        &self,
493        original_name: &str,
494        rename_all_rule: Option<RenameRule>,
495        direct_rename: &Option<String>,
496        attrs: &SerdeAttributes,
497        is_variant: bool,
498    ) -> Result<Cow<'static, str>, Error> {
499        // Direct rename takes precedence
500        if let Some(renamed) = direct_rename {
501            return Ok(Cow::Owned(renamed.clone()));
502        }
503
504        // Check for mode-specific renames
505        match self.mode {
506            SerdeMode::Serialize => {
507                if let Some(renamed) = &attrs.rename_serialize {
508                    return Ok(Cow::Owned(renamed.clone()));
509                }
510            }
511            SerdeMode::Deserialize => {
512                if let Some(renamed) = &attrs.rename_deserialize {
513                    return Ok(Cow::Owned(renamed.clone()));
514                }
515            }
516            SerdeMode::Both => {
517                // For Both mode, don't use mode-specific renames
518                // Only use if serialize and deserialize renames match
519                if let (Some(ser), Some(de)) = (&attrs.rename_serialize, &attrs.rename_deserialize)
520                    && ser == de
521                {
522                    return Ok(Cow::Owned(ser.clone()));
523                }
524            }
525        }
526
527        // Apply mode-specific rename_all rule
528        let rule = match self.mode {
529            SerdeMode::Serialize => attrs
530                .rename_all_serialize
531                .or(attrs.rename_all_fields_serialize)
532                .or(rename_all_rule),
533            SerdeMode::Deserialize => attrs
534                .rename_all_deserialize
535                .or(attrs.rename_all_fields_deserialize)
536                .or(rename_all_rule),
537            SerdeMode::Both => {
538                // For Both mode, use common rename_all or only if both modes match
539                if let (Some(ser), Some(de)) =
540                    (attrs.rename_all_serialize, attrs.rename_all_deserialize)
541                {
542                    if ser == de {
543                        Some(ser)
544                    } else {
545                        rename_all_rule // Fall back to common rule
546                    }
547                } else {
548                    rename_all_rule
549                }
550            }
551        };
552
553        // Apply rename_all rule
554        if let Some(rule) = rule {
555            let transformed = if is_variant {
556                rule.apply_to_variant(original_name)
557            } else {
558                rule.apply_to_field(original_name)
559            };
560            return Ok(Cow::Owned(transformed));
561        }
562
563        // No transformation needed
564        Ok(Cow::Owned(original_name.to_string()))
565    }
566
567    /// Apply enum tagging transformation to variant fields based on representation
568    /// This transforms the DataType to include tag/content fields for Internal/Adjacent representations
569    fn apply_enum_tagging(
570        &self,
571        repr: &EnumRepr,
572        variant_name: &str,
573        fields: Fields,
574    ) -> Result<Fields, Error> {
575        match repr {
576            EnumRepr::External | EnumRepr::Untagged | EnumRepr::String { .. } => {
577                // No transformation needed for external/untagged enums
578                Ok(fields)
579            }
580            EnumRepr::Internal { tag } => {
581                // Add tag field to the variant
582                self.add_tag_field(tag, variant_name, fields)
583            }
584            EnumRepr::Adjacent { tag, content } => {
585                // Wrap fields in content and add tag field
586                self.add_adjacent_tag_fields(tag, content, variant_name, fields)
587            }
588        }
589    }
590
591    /// Create a literal string type using an enum with a single unit variant
592    fn create_literal_string_type(value: &str) -> DataType {
593        use specta::datatype::EnumVariant;
594
595        let mut literal_enum = Enum::new();
596        let unit_variant = EnumVariant::unit();
597        *literal_enum.variants_mut() = vec![(Cow::Owned(value.to_string()), unit_variant)];
598        DataType::Enum(literal_enum)
599    }
600
601    fn is_valid_internal_tag_payload(ty: &DataType) -> bool {
602        match ty {
603            DataType::Primitive(_) | DataType::List(_) => false,
604            DataType::Tuple(tuple) => tuple.elements().is_empty(),
605            DataType::Nullable(inner) => Self::is_valid_internal_tag_payload(inner),
606            _ => true,
607        }
608    }
609
610    /// Add a tag field to a struct (for `#[serde(tag = "...")]` on structs)
611    fn add_struct_tag_field(
612        &self,
613        tag_name: &str,
614        _struct_type: &Struct,
615        fields: Fields,
616    ) -> Result<Fields, Error> {
617        use specta::datatype::Field;
618
619        // Get the struct name from the transformer
620        let struct_name = self.type_name.as_deref().unwrap_or("Unknown");
621        let tag_type = Self::create_literal_string_type(struct_name);
622
623        match fields {
624            Fields::Named(named) => {
625                let mut new_fields = vec![];
626
627                // Add tag field first
628                let tag_field = Field::new(tag_type);
629                new_fields.push((Cow::Owned(tag_name.to_string()), tag_field));
630
631                // Add existing fields
632                for (field_name, field) in named.fields() {
633                    new_fields.push((field_name.clone(), field.clone()));
634                }
635
636                Ok(internal::construct::fields_named(new_fields, vec![]))
637            }
638            _ => {
639                // Struct tagging only works with named fields
640                Ok(fields)
641            }
642        }
643    }
644
645    /// Add a tag field to variant fields for internally tagged enums
646    fn add_tag_field(
647        &self,
648        tag_name: &str,
649        variant_name: &str,
650        fields: Fields,
651    ) -> Result<Fields, Error> {
652        use specta::datatype::Field;
653
654        let tag_type = Self::create_literal_string_type(variant_name);
655
656        match fields {
657            Fields::Unit => {
658                // Unit variant becomes { tag: "VariantName" }
659                let tag_field = Field::new(tag_type);
660                Ok(internal::construct::fields_named(
661                    vec![(Cow::Owned(tag_name.to_string()), tag_field)],
662                    vec![],
663                ))
664            }
665            Fields::Named(named) => {
666                // Named variant: add tag field to existing fields
667                let mut new_fields = vec![];
668
669                // Add tag field first
670                let tag_field = Field::new(tag_type);
671                new_fields.push((Cow::Owned(tag_name.to_string()), tag_field));
672
673                // Add existing fields
674                for (field_name, field) in named.fields() {
675                    new_fields.push((field_name.clone(), field.clone()));
676                }
677
678                Ok(internal::construct::fields_named(new_fields, vec![]))
679            }
680            Fields::Unnamed(unnamed) => {
681                use specta::datatype::skip_fields;
682
683                let invalid_payload = {
684                    let mut non_skipped_fields = skip_fields(unnamed.fields());
685                    if let Some((_, field_ty)) = non_skipped_fields.next() {
686                        non_skipped_fields.next().is_some()
687                            || !Self::is_valid_internal_tag_payload(field_ty)
688                    } else {
689                        false
690                    }
691                };
692
693                if invalid_payload {
694                    return Err(Error::InvalidInternallyTaggedEnum);
695                }
696
697                // Keep tuple payloads unchanged so exporters can render `{ tag } & payload`
698                // for valid internally tagged tuple variants.
699                Ok(Fields::Unnamed(unnamed))
700            }
701        }
702    }
703
704    /// Add tag and content fields for adjacently tagged enums
705    fn add_adjacent_tag_fields(
706        &self,
707        tag_name: &str,
708        content_name: &str,
709        variant_name: &str,
710        fields: Fields,
711    ) -> Result<Fields, Error> {
712        use specta::datatype::Field;
713
714        let tag_type = Self::create_literal_string_type(variant_name);
715
716        match fields {
717            Fields::Unit => {
718                // Unit variant becomes { tag: "VariantName" } (no content field)
719                let tag_field = Field::new(tag_type);
720                Ok(internal::construct::fields_named(
721                    vec![(Cow::Owned(tag_name.to_string()), tag_field)],
722                    vec![],
723                ))
724            }
725            Fields::Named(named) => {
726                // Named variant: { tag: "VariantName", content: { ...fields } }
727                let mut new_fields = vec![];
728
729                // Add tag field
730                let tag_field = Field::new(tag_type);
731                new_fields.push((Cow::Owned(tag_name.to_string()), tag_field));
732
733                // Wrap existing fields in a struct for content
734                let mut content_struct = Struct::unit();
735                content_struct.set_fields(Fields::Named(named.clone()));
736
737                let content_field = Field::new(DataType::Struct(content_struct));
738                new_fields.push((Cow::Owned(content_name.to_string()), content_field));
739
740                Ok(internal::construct::fields_named(new_fields, vec![]))
741            }
742            Fields::Unnamed(unnamed) => {
743                use specta::datatype::skip_fields;
744
745                // Tuple variant: { tag: "VariantName", content: tuple }
746                let mut new_fields = vec![];
747
748                // Add tag field
749                let tag_field = Field::new(tag_type);
750                new_fields.push((Cow::Owned(tag_name.to_string()), tag_field));
751
752                // Wrap tuple fields as content
753                let tuple_types: Vec<DataType> = skip_fields(unnamed.fields())
754                    .map(|(_, ty)| ty.clone())
755                    .collect();
756
757                // If all tuple fields are skipped, omit content.
758                // This keeps adjacently tagged output aligned with serde behavior.
759                if tuple_types.is_empty() && !unnamed.fields().is_empty() {
760                    return Ok(internal::construct::fields_named(new_fields, vec![]));
761                }
762
763                let content_type = if let [single] = tuple_types.as_slice() {
764                    single.clone()
765                } else {
766                    DataType::Tuple(Tuple::new(tuple_types))
767                };
768
769                let content_field = Field::new(content_type);
770                new_fields.push((Cow::Owned(content_name.to_string()), content_field));
771
772                Ok(internal::construct::fields_named(new_fields, vec![]))
773            }
774        }
775    }
776}
777
778/// Parse serde attributes from a vector of RuntimeAttribute
779fn parse_serde_attributes(attributes: &[RuntimeAttribute]) -> Result<SerdeAttributes, Error> {
780    let mut attrs = SerdeAttributes::default();
781
782    for attr in attributes {
783        if attr.path == "serde" {
784            parse_serde_attribute_content(&attr.kind, &mut attrs)?;
785        }
786    }
787
788    Ok(attrs)
789}
790
791/// Parse the content of a serde attribute
792fn parse_serde_attribute_content(
793    meta: &RuntimeMeta,
794    attrs: &mut SerdeAttributes,
795) -> Result<(), Error> {
796    match meta {
797        RuntimeMeta::Path(path) => {
798            // Handle path-only attributes (e.g., #[serde(untagged)], #[serde(skip)])
799            parse_serde_path_attribute(attrs, path);
800        }
801        RuntimeMeta::NameValue { key, value } => {
802            match key.as_str() {
803                "rename" => {
804                    if let RuntimeValue::Literal(RuntimeLiteral::Str(name)) = value {
805                        attrs.rename = Some(name.clone());
806                    }
807                }
808                "rename_all" => {
809                    if let RuntimeValue::Literal(RuntimeLiteral::Str(rule_str)) = value {
810                        attrs.rename_all = Some(
811                            RenameRule::from_str(rule_str)
812                                .map_err(|_| Error::InvalidUsageOfSkip)?,
813                        ); // TODO: Better error
814                    }
815                }
816                "rename_all_fields" => {
817                    if let RuntimeValue::Literal(RuntimeLiteral::Str(rule_str)) = value {
818                        attrs.rename_all_fields = Some(
819                            RenameRule::from_str(rule_str)
820                                .map_err(|_| Error::InvalidUsageOfSkip)?,
821                        );
822                    }
823                }
824                "tag" => {
825                    if let RuntimeValue::Literal(RuntimeLiteral::Str(tag_name)) = value {
826                        attrs.tag = Some(tag_name.clone());
827                        // If we have a tag, this is an internally tagged enum
828                        if attrs.repr.is_none() {
829                            attrs.repr = Some(EnumRepr::Internal {
830                                tag: Cow::Owned(tag_name.clone()),
831                            });
832                        }
833                    }
834                }
835                "content" => {
836                    if let RuntimeValue::Literal(RuntimeLiteral::Str(content_name)) = value {
837                        attrs.content = Some(content_name.clone());
838                    }
839                }
840                "default" => match value {
841                    RuntimeValue::Literal(RuntimeLiteral::Bool(true)) => attrs.default = true,
842                    RuntimeValue::Literal(RuntimeLiteral::Str(func_path)) => {
843                        attrs.default_with = Some(func_path.clone());
844                    }
845                    RuntimeValue::Expr(func_path) => attrs.default_with = Some(func_path.clone()),
846                    _ => {}
847                },
848                "remote" => {
849                    if let RuntimeValue::Literal(RuntimeLiteral::Str(remote_type)) = value {
850                        attrs.remote = Some(remote_type.clone());
851                    }
852                }
853                "from" => {
854                    if let RuntimeValue::Literal(RuntimeLiteral::Str(from_type)) = value {
855                        attrs.from = Some(from_type.clone());
856                    }
857                }
858                "try_from" => {
859                    if let RuntimeValue::Literal(RuntimeLiteral::Str(try_from_type)) = value {
860                        attrs.try_from = Some(try_from_type.clone());
861                    }
862                }
863                "into" => {
864                    if let RuntimeValue::Literal(RuntimeLiteral::Str(into_type)) = value {
865                        attrs.into = Some(into_type.clone());
866                    }
867                }
868                "alias" => {
869                    if let RuntimeValue::Literal(RuntimeLiteral::Str(alias_name)) = value {
870                        attrs.alias.push(alias_name.clone());
871                    }
872                }
873                "serialize_with" => {
874                    if let RuntimeValue::Literal(RuntimeLiteral::Str(serialize_fn)) = value {
875                        attrs.serialize_with = Some(serialize_fn.clone());
876                    }
877                }
878                "deserialize_with" => {
879                    if let RuntimeValue::Literal(RuntimeLiteral::Str(deserialize_fn)) = value {
880                        attrs.deserialize_with = Some(deserialize_fn.clone());
881                    }
882                }
883                "with" => match value {
884                    RuntimeValue::Literal(RuntimeLiteral::Str(with_module))
885                    | RuntimeValue::Expr(with_module) => {
886                        attrs.with = Some(with_module.clone());
887                    }
888                    _ => {}
889                },
890                _ => {}
891            }
892        }
893        RuntimeMeta::List(list) => {
894            // Check if this is a complex attribute with serialize/deserialize modifiers
895            let mut has_serialize_deserialize = false;
896            for nested in list {
897                if let RuntimeNestedMeta::Meta(RuntimeMeta::NameValue { key, .. }) = nested
898                    && (key == "serialize" || key == "deserialize")
899                {
900                    has_serialize_deserialize = true;
901                    break;
902                }
903            }
904
905            if has_serialize_deserialize {
906                // This is a complex attribute like rename(serialize="...", deserialize="...")
907                for nested in list {
908                    if let RuntimeNestedMeta::Meta(nested_meta) = nested {
909                        parse_complex_serde_attribute(nested_meta, attrs, "rename")?;
910                    }
911                }
912            } else {
913                // Regular list processing
914                for nested in list {
915                    match nested {
916                        RuntimeNestedMeta::Meta(nested_meta) => {
917                            parse_serde_attribute_content(nested_meta, attrs)?;
918                        }
919                        RuntimeNestedMeta::Literal(RuntimeLiteral::Str(s)) => {
920                            // Handle string literals that might be path attributes
921                            parse_serde_path_attribute(attrs, s);
922                        }
923                        RuntimeNestedMeta::Expr(_) => {}
924                        RuntimeNestedMeta::Literal(_) => {
925                            // Handle other literal values in lists if needed
926                        }
927                    }
928                }
929            }
930        }
931    }
932
933    // Handle special cases for enum representation
934    if let (Some(tag), Some(content)) = (&attrs.tag, &attrs.content) {
935        attrs.repr = Some(EnumRepr::Adjacent {
936            tag: Cow::Owned(tag.clone()),
937            content: Cow::Owned(content.clone()),
938        });
939    }
940
941    if attrs.untagged {
942        attrs.repr = Some(EnumRepr::Untagged);
943    }
944
945    Ok(())
946}
947
948fn parse_complex_serde_attribute(
949    meta: &RuntimeMeta,
950    attrs: &mut SerdeAttributes,
951    parent_key: &str,
952) -> Result<(), Error> {
953    match meta {
954        RuntimeMeta::NameValue { key, value } => match key.as_str() {
955            "serialize" => {
956                if let RuntimeValue::Literal(RuntimeLiteral::Str(name)) = value {
957                    match parent_key {
958                        "rename" => attrs.rename_serialize = Some(name.clone()),
959                        "rename_all" => {
960                            if let Ok(rule) = RenameRule::from_str(name) {
961                                attrs.rename_all_serialize = Some(rule);
962                            }
963                        }
964                        "rename_all_fields" => {
965                            if let Ok(rule) = RenameRule::from_str(name) {
966                                attrs.rename_all_fields_serialize = Some(rule);
967                            }
968                        }
969                        _ => {}
970                    }
971                }
972            }
973            "deserialize" => {
974                if let RuntimeValue::Literal(RuntimeLiteral::Str(name)) = value {
975                    match parent_key {
976                        "rename" => attrs.rename_deserialize = Some(name.clone()),
977                        "rename_all" => {
978                            if let Ok(rule) = RenameRule::from_str(name) {
979                                attrs.rename_all_deserialize = Some(rule);
980                            }
981                        }
982                        "rename_all_fields" => {
983                            if let Ok(rule) = RenameRule::from_str(name) {
984                                attrs.rename_all_fields_deserialize = Some(rule);
985                            }
986                        }
987                        _ => {}
988                    }
989                }
990            }
991            _ => {}
992        },
993        RuntimeMeta::List(list) => {
994            // Handle nested complex attributes
995            for nested in list {
996                if let RuntimeNestedMeta::Meta(nested_meta) = nested {
997                    parse_complex_serde_attribute(nested_meta, attrs, parent_key)?;
998                }
999            }
1000        }
1001        _ => {}
1002    }
1003    Ok(())
1004}
1005
1006/// Parse string attributes that are commonly used with serde
1007/// This is a helper for parsing path-only attributes like #[serde(skip)]
1008fn parse_serde_path_attribute(attrs: &mut SerdeAttributes, attribute_name: &str) {
1009    match attribute_name {
1010        "skip" => attrs.skip = true,
1011        "skip_serializing" => attrs.skip_serializing = true,
1012        "skip_deserializing" => attrs.skip_deserializing = true,
1013        "flatten" => attrs.flatten = true,
1014        "default" => attrs.default = true,
1015        "transparent" => attrs.transparent = true,
1016        "untagged" => attrs.untagged = true,
1017        "deny_unknown_fields" => attrs.deny_unknown_fields = true,
1018        "other" => attrs.other = true,
1019        _ => {}
1020    }
1021}
1022
1023/// Parse serde field attributes from a vector of RuntimeAttribute
1024#[allow(dead_code)]
1025fn parse_serde_field_attributes(attrs: &[RuntimeAttribute]) -> Result<SerdeFieldAttributes, Error> {
1026    let mut result = SerdeFieldAttributes {
1027        base: parse_serde_attributes(attrs)?,
1028        ..Default::default()
1029    };
1030
1031    for attr in attrs {
1032        if attr.path == "serde" {
1033            parse_serde_field_attribute_content(&attr.kind, &mut result)?;
1034        }
1035    }
1036
1037    Ok(result)
1038}
1039
1040/// Parse the content of a serde field attribute
1041#[allow(dead_code)]
1042fn parse_serde_field_attribute_content(
1043    meta: &RuntimeMeta,
1044    attrs: &mut SerdeFieldAttributes,
1045) -> Result<(), Error> {
1046    // First parse as base attributes
1047    parse_serde_attribute_content(meta, &mut attrs.base)?;
1048
1049    // Then parse field-specific attributes
1050    match meta {
1051        RuntimeMeta::Path(_path) => {
1052            // Path-only attributes are already handled by parse_serde_attribute_content above
1053        }
1054        RuntimeMeta::NameValue { key, value } => match key.as_str() {
1055            "alias" => {
1056                if let RuntimeValue::Literal(RuntimeLiteral::Str(alias_name)) = value {
1057                    attrs.alias.push(alias_name.clone());
1058                }
1059            }
1060            "serialize_with" => {
1061                if let RuntimeValue::Literal(RuntimeLiteral::Str(func_name)) = value {
1062                    attrs.serialize_with = Some(func_name.clone());
1063                }
1064            }
1065            "deserialize_with" => {
1066                if let RuntimeValue::Literal(RuntimeLiteral::Str(func_name)) = value {
1067                    attrs.deserialize_with = Some(func_name.clone());
1068                }
1069            }
1070            "with" => match value {
1071                RuntimeValue::Literal(RuntimeLiteral::Str(module_path))
1072                | RuntimeValue::Expr(module_path) => {
1073                    attrs.with = Some(module_path.clone());
1074                }
1075                _ => {}
1076            },
1077            "skip_serializing_if" => {
1078                if let RuntimeValue::Literal(RuntimeLiteral::Str(func_name)) = value {
1079                    attrs.skip_serializing_if = Some(func_name.clone());
1080                }
1081            }
1082            _ => {}
1083        },
1084        RuntimeMeta::List(list) => {
1085            for nested in list {
1086                if let RuntimeNestedMeta::Meta(nested_meta) = nested {
1087                    parse_serde_field_attribute_content(nested_meta, attrs)?;
1088                }
1089            }
1090        }
1091    }
1092
1093    Ok(())
1094}
1095
1096fn parse_field_serde_attributes(
1097    attributes: &[specta::datatype::RuntimeAttribute],
1098) -> Result<SerdeFieldAttributes, Error> {
1099    parse_serde_field_attributes(attributes)
1100}
1101
1102// #[cfg(test)]
1103// mod tests {
1104//     use super::*;
1105//     use specta::datatype::Primitive;
1106
1107//     #[test]
1108//     fn test_rename_rule_parsing() {
1109//         let mut attrs = SerdeAttributes::default();
1110//         let meta = RuntimeMeta::NameValue {
1111//             key: "rename_all".to_string(),
1112//             value: RuntimeLiteral::Str("camelCase".to_string()),
1113//         };
1114
1115//         parse_serde_attribute_content(&meta, &mut attrs).expect("Failed to parse serde attribute");
1116//         assert_eq!(attrs.rename_all, Some(RenameRule::CamelCase));
1117//     }
1118
1119//     #[test]
1120//     fn test_direct_rename() {
1121//         let mut attrs = SerdeAttributes::default();
1122//         let meta = RuntimeMeta::NameValue {
1123//             key: "rename".to_string(),
1124//             value: RuntimeLiteral::Str("customName".to_string()),
1125//         };
1126
1127//         parse_serde_attribute_content(&meta, &mut attrs).expect("Failed to parse serde attribute");
1128//         assert_eq!(attrs.rename, Some("customName".to_string()));
1129//     }
1130
1131//     #[test]
1132//     fn test_skip_attributes() {
1133//         let mut attrs = SerdeAttributes::default();
1134
1135//         // Test various skip scenarios
1136//         let transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1137//         attrs.skip = true;
1138//         assert!(transformer.should_skip_type(&attrs));
1139
1140//         attrs.skip = false;
1141//         attrs.skip_serializing = true;
1142//         assert!(transformer.should_skip_type(&attrs));
1143
1144//         let deserialize_transformer = SerdeTransformer::new(SerdeMode::Deserialize, None);
1145//         assert!(!deserialize_transformer.should_skip_type(&attrs));
1146//     }
1147
1148//     #[test]
1149//     fn test_all_rename_rules() {
1150//         let test_cases = vec![
1151//             ("lowercase", RenameRule::LowerCase),
1152//             ("UPPERCASE", RenameRule::UpperCase),
1153//             ("PascalCase", RenameRule::PascalCase),
1154//             ("camelCase", RenameRule::CamelCase),
1155//             ("snake_case", RenameRule::SnakeCase),
1156//             ("SCREAMING_SNAKE_CASE", RenameRule::ScreamingSnakeCase),
1157//             ("kebab-case", RenameRule::KebabCase),
1158//             ("SCREAMING-KEBAB-CASE", RenameRule::ScreamingKebabCase),
1159//         ];
1160
1161//         for (rule_str, expected_rule) in test_cases {
1162//             let mut attrs = SerdeAttributes::default();
1163//             let meta = RuntimeMeta::NameValue {
1164//                 key: "rename_all".to_string(),
1165//                 value: RuntimeLiteral::Str(rule_str.to_string()),
1166//             };
1167
1168//             parse_serde_attribute_content(&meta, &mut attrs)
1169//                 .expect("Failed to parse serde attribute");
1170//             assert_eq!(
1171//                 attrs.rename_all,
1172//                 Some(expected_rule),
1173//                 "Failed for rule: {}",
1174//                 rule_str
1175//             );
1176//         }
1177//     }
1178
1179//     #[test]
1180//     fn test_rename_rule_application() {
1181//         let transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1182
1183//         // Test field renaming
1184//         let result = transformer
1185//             .apply_rename_rule(
1186//                 "test_field",
1187//                 Some(RenameRule::CamelCase),
1188//                 &None,
1189//                 &SerdeAttributes::default(),
1190//                 false,
1191//             )
1192//             .unwrap();
1193//         assert_eq!(result, "testField");
1194
1195//         // Test variant renaming
1196//         let result = transformer
1197//             .apply_rename_rule(
1198//                 "TestVariant",
1199//                 Some(RenameRule::SnakeCase),
1200//                 &None,
1201//                 &SerdeAttributes::default(),
1202//                 true,
1203//             )
1204//             .unwrap();
1205//         assert_eq!(result, "test_variant");
1206
1207//         // Test direct rename takes precedence
1208//         let result = transformer
1209//             .apply_rename_rule(
1210//                 "test_field",
1211//                 Some(RenameRule::CamelCase),
1212//                 &Some("customName".to_string()),
1213//                 &SerdeAttributes::default(),
1214//                 false,
1215//             )
1216//             .unwrap();
1217//         assert_eq!(result, "customName");
1218//     }
1219
1220//     #[test]
1221//     fn test_tag_parsing() {
1222//         let mut attrs = SerdeAttributes::default();
1223//         let meta = RuntimeMeta::NameValue {
1224//             key: "tag".to_string(),
1225//             value: RuntimeLiteral::Str("type".to_string()),
1226//         };
1227
1228//         parse_serde_attribute_content(&meta, &mut attrs).expect("Failed to parse serde attribute");
1229//         assert_eq!(attrs.tag, Some("type".to_string()));
1230//         // Should automatically set internal representation
1231//         match attrs.repr {
1232//             Some(EnumRepr::Internal { tag }) => assert_eq!(tag, "type"),
1233//             _ => panic!("Expected internal enum representation"),
1234//         }
1235//     }
1236
1237//     #[test]
1238//     fn test_adjacent_tag_parsing() {
1239//         let mut attrs = SerdeAttributes::default();
1240
1241//         // Set tag first
1242//         let tag_meta = RuntimeMeta::NameValue {
1243//             key: "tag".to_string(),
1244//             value: RuntimeLiteral::Str("type".to_string()),
1245//         };
1246//         parse_serde_attribute_content(&tag_meta, &mut attrs).expect("Failed to parse tag");
1247
1248//         // Set content second
1249//         let content_meta = RuntimeMeta::NameValue {
1250//             key: "content".to_string(),
1251//             value: RuntimeLiteral::Str("data".to_string()),
1252//         };
1253//         parse_serde_attribute_content(&content_meta, &mut attrs).expect("Failed to parse content");
1254
1255//         // Should create adjacent representation
1256//         match attrs.repr {
1257//             Some(EnumRepr::Adjacent { tag, content }) => {
1258//                 assert_eq!(tag, "type");
1259//                 assert_eq!(content, "data");
1260//             }
1261//             _ => panic!("Expected adjacent enum representation"),
1262//         }
1263//     }
1264
1265//     #[test]
1266//     fn test_default_attribute() {
1267//         let mut attrs = SerdeAttributes::default();
1268//         let meta = RuntimeMeta::NameValue {
1269//             key: "default".to_string(),
1270//             value: RuntimeLiteral::Bool(true),
1271//         };
1272
1273//         parse_serde_attribute_content(&meta, &mut attrs).expect("Failed to parse serde attribute");
1274//         assert!(attrs.default);
1275//     }
1276
1277//     #[test]
1278//     fn test_primitive_type_passthrough() {
1279//         let mut transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1280//         let primitive = DataType::Primitive(Primitive::String);
1281
1282//         let result = transformer.transform_datatype(&primitive).unwrap();
1283//         assert_eq!(result, primitive);
1284//     }
1285
1286//     #[test]
1287//     fn test_nullable_type_transformation() {
1288//         let mut transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1289//         let nullable = DataType::Nullable(Box::new(DataType::Primitive(Primitive::String)));
1290
1291//         let result = transformer.transform_datatype(&nullable).unwrap();
1292//         match result {
1293//             DataType::Nullable(inner) => {
1294//                 assert_eq!(*inner.as_ref(), DataType::Primitive(Primitive::String));
1295//             }
1296//             _ => panic!("Expected nullable type"),
1297//         }
1298//     }
1299
1300//     #[test]
1301//     fn test_list_type_transformation() {
1302//         let mut transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1303//         let list = DataType::List(specta::datatype::List::new(DataType::Primitive(
1304//             Primitive::String,
1305//         )));
1306
1307//         let result = transformer.transform_datatype(&list).unwrap();
1308//         match result {
1309//             DataType::List(list_result) => {
1310//                 assert_eq!(*list_result.ty(), DataType::Primitive(Primitive::String));
1311//             }
1312//             _ => panic!("Expected list type"),
1313//         }
1314//     }
1315
1316//     #[test]
1317//     fn test_mode_specific_skip_behavior() {
1318//         let mut attrs = SerdeAttributes::default();
1319
1320//         // Test skip_serializing only affects serialize mode
1321//         attrs.skip_serializing = true;
1322//         let ser_transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1323//         let de_transformer = SerdeTransformer::new(SerdeMode::Deserialize, None);
1324
1325//         assert!(ser_transformer.should_skip_type(&attrs));
1326//         assert!(!de_transformer.should_skip_type(&attrs));
1327
1328//         // Reset and test skip_deserializing
1329//         attrs.skip_serializing = false;
1330//         attrs.skip_deserializing = true;
1331
1332//         assert!(!ser_transformer.should_skip_type(&attrs));
1333//         assert!(de_transformer.should_skip_type(&attrs));
1334
1335//         // Test universal skip
1336//         attrs.skip_deserializing = false;
1337//         attrs.skip = true;
1338
1339//         assert!(ser_transformer.should_skip_type(&attrs));
1340//         assert!(de_transformer.should_skip_type(&attrs));
1341//     }
1342
1343//     #[test]
1344//     fn test_transparent_struct_handling() {
1345//         let mut transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1346
1347//         // Create a transparent struct with single field using List format
1348//         let transparent_attr = RuntimeAttribute {
1349//             path: "serde".to_string(),
1350//             kind: RuntimeMeta::List(vec![RuntimeNestedMeta::Literal(RuntimeLiteral::Str(
1351//                 "transparent".to_string(),
1352//             ))]),
1353//         };
1354
1355//         let field = specta::datatype::Field::new(DataType::Primitive(Primitive::String));
1356//         let mut struct_dt = match Struct::unnamed().field(field).build() {
1357//             DataType::Struct(s) => s,
1358//             _ => unreachable!(),
1359//         };
1360//         struct_dt.set_attributes(vec![transparent_attr]);
1361
1362//         let datatype = DataType::Struct(struct_dt);
1363//         let result = transformer.transform_datatype(&datatype).unwrap();
1364
1365//         // Should resolve to the inner type
1366//         assert_eq!(result, DataType::Primitive(Primitive::String));
1367//     }
1368
1369//     #[test]
1370//     fn test_field_attributes_parsing() {
1371//         let serialize_with_attr = RuntimeAttribute {
1372//             path: "serde".to_string(),
1373//             kind: RuntimeMeta::NameValue {
1374//                 key: "serialize_with".to_string(),
1375//                 value: RuntimeLiteral::Str("custom_serialize".to_string()),
1376//             },
1377//         };
1378
1379//         let attrs = parse_serde_field_attributes(&[serialize_with_attr]).unwrap();
1380//         assert_eq!(attrs.serialize_with, Some("custom_serialize".to_string()));
1381//     }
1382
1383//     #[test]
1384//     fn test_other_attribute() {
1385//         let mut attrs = SerdeAttributes::default();
1386//         parse_serde_path_attribute(&mut attrs, "other");
1387//         assert!(attrs.other);
1388//     }
1389
1390//     #[test]
1391//     fn test_alias_attribute() {
1392//         let mut attrs = SerdeAttributes::default();
1393//         let meta = RuntimeMeta::NameValue {
1394//             key: "alias".to_string(),
1395//             value: RuntimeLiteral::Str("alternative_name".to_string()),
1396//         };
1397
1398//         parse_serde_attribute_content(&meta, &mut attrs).expect("Failed to parse serde attribute");
1399//         assert_eq!(attrs.alias, vec!["alternative_name".to_string()]);
1400//     }
1401
1402//     #[test]
1403//     fn test_serialize_with_attribute() {
1404//         let mut attrs = SerdeAttributes::default();
1405//         let meta = RuntimeMeta::NameValue {
1406//             key: "serialize_with".to_string(),
1407//             value: RuntimeLiteral::Str("custom_serialize".to_string()),
1408//         };
1409
1410//         parse_serde_attribute_content(&meta, &mut attrs).expect("Failed to parse serde attribute");
1411//         assert_eq!(attrs.serialize_with, Some("custom_serialize".to_string()));
1412//     }
1413
1414//     #[test]
1415//     fn test_with_attribute() {
1416//         let mut attrs = SerdeAttributes::default();
1417//         let meta = RuntimeMeta::NameValue {
1418//             key: "with".to_string(),
1419//             value: RuntimeLiteral::Str("custom_module".to_string()),
1420//         };
1421
1422//         parse_serde_attribute_content(&meta, &mut attrs).expect("Failed to parse serde attribute");
1423//         assert_eq!(attrs.with, Some("custom_module".to_string()));
1424//     }
1425
1426//     #[test]
1427//     fn test_complex_rename_attribute() {
1428//         let mut attrs = SerdeAttributes::default();
1429
1430//         // Simulate parsing rename(serialize = "ser_name", deserialize = "de_name")
1431//         let serialize_meta = RuntimeMeta::NameValue {
1432//             key: "serialize".to_string(),
1433//             value: RuntimeLiteral::Str("ser_name".to_string()),
1434//         };
1435//         let deserialize_meta = RuntimeMeta::NameValue {
1436//             key: "deserialize".to_string(),
1437//             value: RuntimeLiteral::Str("de_name".to_string()),
1438//         };
1439
1440//         parse_complex_serde_attribute(&serialize_meta, &mut attrs, "rename")
1441//             .expect("Failed to parse serialize");
1442//         parse_complex_serde_attribute(&deserialize_meta, &mut attrs, "rename")
1443//             .expect("Failed to parse deserialize");
1444
1445//         assert_eq!(attrs.rename_serialize, Some("ser_name".to_string()));
1446//         assert_eq!(attrs.rename_deserialize, Some("de_name".to_string()));
1447//     }
1448
1449//     #[test]
1450//     fn test_complex_rename_all_attribute() {
1451//         let mut attrs = SerdeAttributes::default();
1452
1453//         // Simulate parsing rename_all(serialize = "camelCase", deserialize = "snake_case")
1454//         let serialize_meta = RuntimeMeta::NameValue {
1455//             key: "serialize".to_string(),
1456//             value: RuntimeLiteral::Str("camelCase".to_string()),
1457//         };
1458//         let deserialize_meta = RuntimeMeta::NameValue {
1459//             key: "deserialize".to_string(),
1460//             value: RuntimeLiteral::Str("snake_case".to_string()),
1461//         };
1462
1463//         parse_complex_serde_attribute(&serialize_meta, &mut attrs, "rename_all")
1464//             .expect("Failed to parse serialize");
1465//         parse_complex_serde_attribute(&deserialize_meta, &mut attrs, "rename_all")
1466//             .expect("Failed to parse deserialize");
1467
1468//         assert_eq!(attrs.rename_all_serialize, Some(RenameRule::CamelCase));
1469//         assert_eq!(attrs.rename_all_deserialize, Some(RenameRule::SnakeCase));
1470//     }
1471
1472//     #[test]
1473//     fn test_mode_specific_rename_behavior() {
1474//         let mut attrs = SerdeAttributes::default();
1475//         attrs.rename_serialize = Some("ser_name".to_string());
1476//         attrs.rename_deserialize = Some("de_name".to_string());
1477
1478//         let ser_transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1479//         let de_transformer = SerdeTransformer::new(SerdeMode::Deserialize, None);
1480
1481//         let ser_result = ser_transformer
1482//             .apply_rename_rule("original", None, &None, &attrs, false)
1483//             .unwrap();
1484//         assert_eq!(ser_result, "ser_name");
1485
1486//         let de_result = de_transformer
1487//             .apply_rename_rule("original", None, &None, &attrs, false)
1488//             .unwrap();
1489//         assert_eq!(de_result, "de_name");
1490//     }
1491
1492//     #[test]
1493//     fn test_mode_specific_rename_all_behavior() {
1494//         let mut attrs = SerdeAttributes::default();
1495//         attrs.rename_all_serialize = Some(RenameRule::CamelCase);
1496//         attrs.rename_all_deserialize = Some(RenameRule::SnakeCase);
1497
1498//         let ser_transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1499//         let de_transformer = SerdeTransformer::new(SerdeMode::Deserialize, None);
1500
1501//         // Test field renaming (fields start as snake_case in Rust)
1502//         let ser_result = ser_transformer
1503//             .apply_rename_rule("test_field", None, &None, &attrs, false)
1504//             .unwrap();
1505//         assert_eq!(ser_result, "testField");
1506
1507//         let de_result = de_transformer
1508//             .apply_rename_rule("test_field", None, &None, &attrs, false)
1509//             .unwrap();
1510//         assert_eq!(de_result, "test_field"); // snake_case rule returns input unchanged for fields
1511
1512//         // Test variant renaming (variants start as PascalCase in Rust)
1513//         let ser_result = ser_transformer
1514//             .apply_rename_rule("TestVariant", None, &None, &attrs, true)
1515//             .unwrap();
1516//         assert_eq!(ser_result, "testVariant"); // camelCase
1517
1518//         let de_result = de_transformer
1519//             .apply_rename_rule("TestVariant", None, &None, &attrs, true)
1520//             .unwrap();
1521//         assert_eq!(de_result, "test_variant"); // snake_case
1522//     }
1523
1524//     #[test]
1525//     fn test_both_mode_skip_behavior() {
1526//         let mut attrs = SerdeAttributes::default();
1527//         let both_transformer = SerdeTransformer::new(SerdeMode::Both, None);
1528
1529//         // Test that Both mode only skips if both modes skip
1530//         attrs.skip_serializing = true;
1531//         attrs.skip_deserializing = false;
1532//         assert!(!both_transformer.should_skip_type(&attrs));
1533
1534//         attrs.skip_serializing = false;
1535//         attrs.skip_deserializing = true;
1536//         assert!(!both_transformer.should_skip_type(&attrs));
1537
1538//         // Should skip only when both are true
1539//         attrs.skip_serializing = true;
1540//         attrs.skip_deserializing = true;
1541//         assert!(both_transformer.should_skip_type(&attrs));
1542
1543//         // Universal skip should still work
1544//         attrs.skip_serializing = false;
1545//         attrs.skip_deserializing = false;
1546//         attrs.skip = true;
1547//         assert!(both_transformer.should_skip_type(&attrs));
1548//     }
1549
1550//     #[test]
1551//     fn test_both_mode_rename_behavior() {
1552//         let both_transformer = SerdeTransformer::new(SerdeMode::Both, None);
1553//         let mut attrs = SerdeAttributes::default();
1554
1555//         // Test that Both mode uses common rename
1556//         attrs.rename = Some("commonName".to_string());
1557//         let result = both_transformer
1558//             .apply_rename_rule("original", None, &attrs.rename, &attrs, false)
1559//             .unwrap();
1560//         assert_eq!(result, "commonName");
1561
1562//         // Test that Both mode uses matching mode-specific renames
1563//         attrs.rename = None;
1564//         attrs.rename_serialize = Some("sameName".to_string());
1565//         attrs.rename_deserialize = Some("sameName".to_string());
1566//         let result = both_transformer
1567//             .apply_rename_rule("original", None, &None, &attrs, false)
1568//             .unwrap();
1569//         assert_eq!(result, "sameName");
1570
1571//         // Test that Both mode ignores non-matching mode-specific renames
1572//         attrs.rename_serialize = Some("serName".to_string());
1573//         attrs.rename_deserialize = Some("deName".to_string());
1574//         let result = both_transformer
1575//             .apply_rename_rule("original", None, &None, &attrs, false)
1576//             .unwrap();
1577//         assert_eq!(result, "original"); // Falls back to original name
1578//     }
1579
1580//     #[test]
1581//     fn test_both_mode_rename_all_behavior() {
1582//         let both_transformer = SerdeTransformer::new(SerdeMode::Both, None);
1583//         let mut attrs = SerdeAttributes::default();
1584
1585//         // Test that Both mode uses common rename_all
1586//         let result = both_transformer
1587//             .apply_rename_rule(
1588//                 "test_field",
1589//                 Some(RenameRule::CamelCase),
1590//                 &None,
1591//                 &attrs,
1592//                 false,
1593//             )
1594//             .unwrap();
1595//         assert_eq!(result, "testField");
1596
1597//         // Test that Both mode uses matching mode-specific rename_all
1598//         attrs.rename_all_serialize = Some(RenameRule::PascalCase);
1599//         attrs.rename_all_deserialize = Some(RenameRule::PascalCase);
1600//         let result = both_transformer
1601//             .apply_rename_rule("test_field", None, &None, &attrs, false)
1602//             .unwrap();
1603//         assert_eq!(result, "TestField");
1604
1605//         // Test that Both mode falls back to common rule when modes differ
1606//         attrs.rename_all_serialize = Some(RenameRule::CamelCase);
1607//         attrs.rename_all_deserialize = Some(RenameRule::SnakeCase);
1608//         let result = both_transformer
1609//             .apply_rename_rule(
1610//                 "test_field",
1611//                 Some(RenameRule::PascalCase),
1612//                 &None,
1613//                 &attrs,
1614//                 false,
1615//             )
1616//             .unwrap();
1617//         assert_eq!(result, "TestField"); // Uses common rule
1618//     }
1619
1620//     #[test]
1621//     fn test_variant_attribute_parsing() {
1622//         // Test that variant attributes are parsed when transforming enums
1623//         let variant_attr = RuntimeAttribute {
1624//             path: "serde".to_string(),
1625//             kind: RuntimeMeta::NameValue {
1626//                 key: "rename".to_string(),
1627//                 value: RuntimeLiteral::Str("custom_variant".to_string()),
1628//             },
1629//         };
1630
1631//         let attrs = parse_serde_attributes(&[variant_attr]).unwrap();
1632//         assert_eq!(attrs.rename, Some("custom_variant".to_string()));
1633//     }
1634
1635//     #[test]
1636//     fn test_internally_tagged_unit_variants_with_rename() {
1637//         use specta::datatype::{Enum, EnumVariant};
1638//         use std::borrow::Cow;
1639
1640//         // Create an enum with only unit variants
1641//         let mut test_enum = Enum::new();
1642//         *test_enum.variants_mut() = vec![
1643//             (Cow::Borrowed("A"), EnumVariant::unit()),
1644//             (Cow::Borrowed("B"), EnumVariant::unit()),
1645//             (Cow::Borrowed("C"), EnumVariant::unit()),
1646//         ];
1647
1648//         // Add serde attributes for internal tagging + rename_all
1649//         *test_enum.attributes_mut() = vec![
1650//             RuntimeAttribute {
1651//                 path: "serde".to_string(),
1652//                 kind: RuntimeMeta::NameValue {
1653//                     key: "tag".to_string(),
1654//                     value: RuntimeLiteral::Str("phase".to_string()),
1655//                 },
1656//             },
1657//             RuntimeAttribute {
1658//                 path: "serde".to_string(),
1659//                 kind: RuntimeMeta::NameValue {
1660//                     key: "rename_all".to_string(),
1661//                     value: RuntimeLiteral::Str("snake_case".to_string()),
1662//                 },
1663//             },
1664//         ];
1665
1666//         let mut transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1667//         let result = transformer.transform_enum(&test_enum).unwrap();
1668
1669//         // Should produce an enum where each unit variant is transformed into a named field
1670//         // with a tag field containing a literal string type
1671//         match result {
1672//             DataType::Enum(transformed_enum) => {
1673//                 assert_eq!(transformed_enum.variants().len(), 3);
1674
1675//                 // Check first variant
1676//                 let (name, variant) = &transformed_enum.variants()[0];
1677//                 assert_eq!(name.as_ref(), "a"); // snake_case transformation
1678
1679//                 // Variant should have named fields with a "phase" tag
1680//                 match variant.fields() {
1681//                     Fields::Named(named) => {
1682//                         assert_eq!(named.fields().len(), 1);
1683//                         let (field_name, _field) = &named.fields()[0];
1684//                         assert_eq!(field_name.as_ref(), "phase");
1685//                     }
1686//                     _ => panic!("Expected named fields for internally tagged unit variant"),
1687//                 }
1688//             }
1689//             _ => panic!("Expected enum type"),
1690//         }
1691//     }
1692
1693//     #[test]
1694//     fn test_adjacently_tagged_unit_variants_with_rename() {
1695//         use specta::datatype::{Enum, EnumVariant};
1696//         use std::borrow::Cow;
1697
1698//         // Create an enum with only unit variants
1699//         let mut test_enum = Enum::new();
1700//         *test_enum.variants_mut() = vec![
1701//             (Cow::Borrowed("VariantA"), EnumVariant::unit()),
1702//             (Cow::Borrowed("VariantB"), EnumVariant::unit()),
1703//         ];
1704
1705//         // Add serde attributes for adjacent tagging + rename_all
1706//         *test_enum.attributes_mut() = vec![
1707//             RuntimeAttribute {
1708//                 path: "serde".to_string(),
1709//                 kind: RuntimeMeta::NameValue {
1710//                     key: "tag".to_string(),
1711//                     value: RuntimeLiteral::Str("t".to_string()),
1712//                 },
1713//             },
1714//             RuntimeAttribute {
1715//                 path: "serde".to_string(),
1716//                 kind: RuntimeMeta::NameValue {
1717//                     key: "content".to_string(),
1718//                     value: RuntimeLiteral::Str("c".to_string()),
1719//                 },
1720//             },
1721//             RuntimeAttribute {
1722//                 path: "serde".to_string(),
1723//                 kind: RuntimeMeta::NameValue {
1724//                     key: "rename_all".to_string(),
1725//                     value: RuntimeLiteral::Str("snake_case".to_string()),
1726//                 },
1727//             },
1728//         ];
1729
1730//         let mut transformer = SerdeTransformer::new(SerdeMode::Serialize, None);
1731//         let result = transformer.transform_enum(&test_enum).unwrap();
1732
1733//         // Should produce an enum where each unit variant has a tag field
1734//         // For unit variants, adjacently tagged enums only add the tag (no content)
1735//         match result {
1736//             DataType::Enum(transformed_enum) => {
1737//                 assert_eq!(transformed_enum.variants().len(), 2);
1738
1739//                 // Check first variant
1740//                 let (name, variant) = &transformed_enum.variants()[0];
1741//                 assert_eq!(name.as_ref(), "variant_a"); // snake_case transformation
1742
1743//                 // Unit variants in adjacently tagged enums only have the tag field
1744//                 match variant.fields() {
1745//                     Fields::Named(named) => {
1746//                         assert_eq!(named.fields().len(), 1);
1747//                         let (field_name, _field) = &named.fields()[0];
1748//                         assert_eq!(field_name.as_ref(), "t");
1749//                     }
1750//                     _ => panic!("Expected named fields for adjacently tagged unit variant"),
1751//                 }
1752//             }
1753//             _ => panic!("Expected enum type"),
1754//         }
1755//     }
1756// }