syncdoc_core/
parse.rs

1//! Declarative parsing types using unsynn
2
3use unsynn::*;
4
5/// Parses tokens until `C` is found on the current token tree level.
6pub type VerbatimUntil<C> = Many<Cons<Except<C>, AngleTokenTree>>;
7
8keyword! {
9    /// The "path" keyword
10    pub KPath = "path";
11    /// The "name" keyword
12    pub KName = "name";
13    /// The "cfg_attr" keyword
14    pub KCfgAttr = "cfg_attr";
15    /// The "fn" keyword
16    pub KFn = "fn";
17    /// The "pub" keyword
18    pub KPub = "pub";
19    /// The "async" keyword
20    pub KAsync = "async";
21    /// The "unsafe" keyword
22    pub KUnsafe = "unsafe";
23    /// The "extern" keyword
24    pub KExtern = "extern";
25    /// The "const" keyword
26    pub KConst = "const";
27    /// The "where" keyword
28    pub KWhere = "where";
29    /// The "impl" keyword
30    pub KImpl = "impl";
31    /// The "for" keyword
32    pub KFor = "for";
33    /// The "mod" keyword
34    pub KMod = "mod";
35    /// The "trait" keyword
36    pub KTrait = "trait";
37    /// The "crate" keyword
38    pub KCrate = "crate";
39    /// The "super" keyword
40    pub KSuper = "super";
41    /// The "self" keyword
42    pub KSelf = "self";
43    /// The "mut" keyword
44    pub KMut = "mut";
45    /// The "enum" keyword
46    pub KEnum = "enum";
47    /// The "struct" keyword
48    pub KStruct = "struct";
49    /// The "type" keyword
50    pub KType = "type";
51    /// The "static" keyword
52    pub KStatic = "static";
53}
54
55operator! {
56    /// The "=" operator
57    pub Eq = "=";
58    /// The "&" operator
59    pub And = "&";
60}
61
62unsynn! {
63    /// Parses either a `TokenTree` or `<...>` grouping
64    #[derive(Clone)]
65    pub struct AngleTokenTree(
66        pub Either<Cons<Lt, Vec<Cons<Except<Gt>, AngleTokenTree>>, Gt>, TokenTree>,
67    );
68
69    /// Declarative syncdoc arguments structure
70    pub struct SyncDocInner {
71        /// Comma-delimited list of arguments
72        pub args: Option<CommaDelimitedVec<SyncDocArg>>,
73    }
74
75    /// Single syncdoc argument
76    pub enum SyncDocArg {
77        /// path = "docs"
78        Path(PathArg),
79        /// name = "custom"
80        Name(NameArg),
81        /// cfg_attr = "doc"
82        CfgAttr(CfgAttrArg),
83    }
84
85    /// Path argument: path = "docs"
86    pub struct PathArg {
87        pub _path: KPath,
88        pub _eq: Eq,
89        pub value: LiteralString,
90    }
91
92    /// Name argument: name = "custom"
93    pub struct NameArg {
94        pub _name: KName,
95        pub _eq: Eq,
96        pub value: LiteralString,
97    }
98
99    /// Name argument: name = "custom"
100    pub struct CfgAttrArg {
101        pub _cfg_attr: KCfgAttr,
102        pub _eq: Eq,
103        pub value: LiteralString,
104    }
105
106    /// Complete function signature
107    #[derive(Clone)]
108    pub struct FnSig {
109        /// Optional attributes (#[...])
110        pub attributes: Option<Many<Attribute>>,
111        /// Optional visibility (pub, pub(crate), etc.)
112        pub visibility: Option<Visibility>,
113        /// Optional const modifier
114        pub const_kw: Option<KConst>,
115        /// Optional async modifier
116        pub async_kw: Option<KAsync>,
117        /// Optional unsafe modifier
118        pub unsafe_kw: Option<KUnsafe>,
119        /// Optional extern with optional ABI
120        pub extern_kw: Option<ExternSpec>,
121        /// The "fn" keyword
122        pub _fn: KFn,
123        /// Function name
124        pub name: Ident,
125        /// Optional generic parameters
126        pub generics: Option<Generics>,
127        /// Parameters in parentheses
128        pub params: ParenthesisGroupContaining<Option<CommaDelimitedVec<FnParam>>>,
129        /// Optional return type
130        pub return_type: Option<ReturnTypeFn>,
131        /// Optional where clause
132        pub where_clause: Option<WhereClauses>,
133        pub body: BraceGroup,
134    }
135
136    /// (Outer) Attribute like #[derive(Debug)]
137    #[derive(Clone)]
138    pub struct Attribute {
139        /// Hash symbol
140        pub _hash: Pound,
141        /// Attribute content
142        pub content: BracketGroup,
143    }
144
145    /// Inner attribute like #![forbid(unsafe_code)]
146    #[derive(Clone)]
147    pub struct InnerAttribute {
148        /// Hash symbol
149        pub _hash: Pound,
150        /// Bang symbol
151        pub _bang: Bang,
152        /// Attribute content
153        pub content: BracketGroup,
154    }
155
156    /// Either an inner or outer attribute
157    pub enum AnyAttribute {
158        Inner(InnerAttribute),
159        Outer(Attribute),
160    }
161
162    /// Extern specification with optional ABI
163    #[derive(Clone)]
164    pub enum ExternSpec {
165        /// "extern" with ABI string like extern "C"
166        WithAbi(ExternWithAbi),
167        /// Just "extern"
168        Bare(KExtern),
169    }
170
171    /// Extern with ABI string
172    #[derive(Clone)]
173    pub struct ExternWithAbi {
174        /// The "extern" keyword
175        pub _extern: KExtern,
176        /// The ABI string
177        pub abi: LiteralString,
178    }
179
180    /// Simple visibility parsing
181    #[derive(Clone)]
182    pub enum Visibility {
183        /// "pub(crate)", "pub(super)", etc.
184        Restricted(RestrictedVis),
185        /// Just "pub"
186        Public(KPub),
187    }
188
189    /// Restricted visibility like pub(crate)
190    #[derive(Clone)]
191    pub struct RestrictedVis {
192        /// The "pub" keyword
193        pub _pub: KPub,
194        /// The parentheses with content
195        pub restriction: ParenthesisGroup,
196    }
197
198    /// Simple generics (treat as opaque for now)
199    #[derive(Clone)]
200    pub struct Generics {
201        /// Opening
202        pub _lt: Lt,
203        /// Everything until closing > (opaque)
204        pub content: Many<Cons<Except<Gt>, TokenTree>>,
205        /// Closing >
206        pub _gt: Gt,
207    }
208
209    /// Trait return type: -> Type (stops at ;)
210    #[derive(Clone)]
211    pub struct ReturnTypeTrait {
212        /// Arrow
213        pub _arrow: RArrow,
214        /// Everything until semicolon (opaque)
215        pub return_type: VerbatimUntil<Either<BraceGroup, Semicolon>>,
216    }
217
218    /// Function return type: -> Type (stops at {)
219    #[derive(Clone)]
220    pub struct ReturnTypeFn {
221        /// Arrow
222        pub _arrow: RArrow,
223        /// Everything until brace (opaque)
224        pub return_type: VerbatimUntil<BraceGroup>,
225    }
226
227    /// Represents a single predicate within a `where` clause.
228    #[derive(Clone)]
229    pub struct WhereClause {
230        /// The type or lifetime being constrained (e.g., `T` or `'a`).
231        pub _pred: VerbatimUntil<Colon>,
232        /// The colon separating the constrained item and its bounds.
233        pub _colon: Colon,
234        /// The bounds applied to the type or lifetime (e.g., `Trait` or `'b`).
235        pub bounds: VerbatimUntil<Either<Comma, Semicolon, BraceGroup>>,
236    }
237
238    /// Where clauses: where T: Trait, U: Send
239    #[derive(Clone)]
240    pub struct WhereClauses {
241        /// The `where` keyword.
242        pub _kw_where: KWhere,
243        /// The comma-delimited list of where clause predicates.
244        pub clauses: CommaDelimitedVec<WhereClausePredicate>,
245    }
246
247    /// Single where clause predicate: T: Trait
248    #[derive(Clone)]
249    pub struct WhereClausePredicate {
250        /// The type being constrained (e.g., `T`)
251        pub pred: VerbatimUntil<Colon>,
252        /// The colon
253        pub _colon: Colon,
254        /// The bounds (e.g., `Trait`)
255        pub bounds: VerbatimUntil<Either<Comma, BraceGroup>>,
256    }
257
258    /// Top-level item that can appear in a module
259    #[derive(Clone)]
260    pub enum ModuleItem {
261        /// A trait method signature (no body)
262        TraitMethod(TraitMethodSig),
263        /// A function definition
264        Function(FnSig),
265        /// An impl block
266        ImplBlock(ImplBlockSig),
267        /// A module definition
268        Module(ModuleSig),
269        /// A trait definition
270        Trait(TraitSig),
271        /// An enum definition
272        Enum(EnumSig),
273        /// A struct definition
274        Struct(StructSig),
275        /// A type alias
276        TypeAlias(TypeAliasSig),
277        /// A constant
278        Const(ConstSig),
279        /// A static
280        Static(StaticSig),
281        /// Any other item (use, extern crate, etc.)
282        Other(TokenTree),
283    }
284
285    /// impl Type { ... } block
286    #[derive(Clone)]
287    pub struct ImplBlockSig {
288        /// Optional attributes
289        pub attributes: Option<Many<Attribute>>,
290        /// "impl" keyword
291        pub _impl: KImpl,
292        /// Optional generic parameters
293        pub generics: Option<Generics>,
294        /// Type being implemented (opaque for now)
295        pub target_type: Many<Cons<Except<Either<KFor, BraceGroup>>, TokenTree>>,
296        /// Optional "for Trait" part
297        pub for_trait: Option<Cons<KFor, Many<Cons<Except<BraceGroup>, TokenTree>>>>,
298        /// Optional where clause
299        pub where_clause: Option<WhereClauses>,
300        /// Parsed impl block contents
301        pub items: BraceGroupContaining<ModuleContent>,
302    }
303
304    /// mod name { ... } block
305    #[derive(Clone)]
306    pub struct ModuleSig {
307        /// Optional attributes
308        pub attributes: Option<Many<Attribute>>,
309        /// Optional visibility
310        pub visibility: Option<Visibility>,
311        /// "mod" keyword
312        pub _mod: KMod,
313        /// Module name
314        pub name: Ident,
315        /// Parsed module contents
316        pub items: BraceGroupContaining<ModuleContent>,
317    }
318
319    /// trait Name { ... } block
320    #[derive(Clone)]
321    pub struct TraitSig {
322        /// Optional attributes
323        pub attributes: Option<Many<Attribute>>,
324        /// Optional visibility
325        pub visibility: Option<Visibility>,
326        /// Optional unsafe
327        pub unsafe_kw: Option<KUnsafe>,
328        /// "trait" keyword
329        pub _trait: KTrait,
330        /// Trait name
331        pub name: Ident,
332        /// Optional generic parameters
333        pub generics: Option<Generics>,
334        /// Optional trait bounds
335        pub bounds: Option<Cons<Colon, Many<Cons<Except<Either<KWhere, BraceGroup>>, TokenTree>>>>,
336        /// Optional where clause
337        pub where_clause: Option<WhereClauses>,
338        /// Parsed trait body
339        pub items: BraceGroupContaining<ModuleContent>,
340    }
341
342    /// Trait method signature (no body)
343    #[derive(Clone)]
344    pub struct TraitMethodSig {
345        /// Optional attributes
346        pub attributes: Option<Many<Attribute>>,
347        /// Optional const modifier
348        pub const_kw: Option<KConst>,
349        /// Optional async modifier
350        pub async_kw: Option<KAsync>,
351        /// Optional unsafe modifier
352        pub unsafe_kw: Option<KUnsafe>,
353        /// Optional extern with optional ABI
354        pub extern_kw: Option<ExternSpec>,
355        /// The "fn" keyword
356        pub _fn: KFn,
357        /// Method name
358        pub name: Ident,
359        /// Optional generic parameters
360        pub generics: Option<Generics>,
361        /// Parameters in parentheses
362        pub params: ParenthesisGroupContaining<Option<CommaDelimitedVec<FnParam>>>,
363        /// Optional return type
364        pub return_type: Option<ReturnTypeTrait>,
365        /// Optional where clause
366        pub where_clause: Option<WhereClauses>,
367        /// Semicolon (trait methods end with ;, not {})
368        pub _semi: Semicolon,
369    }
370
371    /// enum Name { ... } block
372    #[derive(Clone)]
373    pub struct EnumSig {
374        /// Optional attributes
375        pub attributes: Option<Many<Attribute>>,
376        /// Optional visibility
377        pub visibility: Option<Visibility>,
378        /// "enum" keyword
379        pub _enum: KEnum,
380        /// Enum name
381        pub name: Ident,
382        /// Optional generic parameters
383        pub generics: Option<Generics>,
384        /// Optional where clause
385        pub where_clause: Option<WhereClauses>,
386        /// Parsed enum variants
387        pub variants: BraceGroupContaining<Option<CommaDelimitedVec<EnumVariant>>>,
388    }
389
390    /// struct Name { ... } or struct Name;
391    #[derive(Clone)]
392    pub struct StructSig {
393        /// Optional attributes
394        pub attributes: Option<Many<Attribute>>,
395        /// Optional visibility
396        pub visibility: Option<Visibility>,
397        /// "struct" keyword
398        pub _struct: KStruct,
399        /// Struct name
400        pub name: Ident,
401        /// Optional generic parameters
402        pub generics: Option<Generics>,
403        /// Optional where clause
404        pub where_clause: Option<WhereClauses>,
405        /// Struct body (could be brace group, tuple, or unit)
406        pub body: StructBody,
407    }
408
409    /// Struct body variants
410    #[derive(Clone)]
411    pub enum StructBody {
412        /// Named fields with parsed field list
413        Named(BraceGroupContaining<Option<CommaDelimitedVec<StructField>>>),
414        /// Tuple fields: (Type, Type)
415        Tuple(Cons<ParenthesisGroup, Semicolon>),
416        /// Unit struct: ;
417        Unit(Semicolon),
418    }
419
420    /// Named struct field: pub name: Type
421    #[derive(Clone)]
422    pub struct StructField {
423        /// Optional attributes
424        pub attributes: Option<Many<Attribute>>,
425        /// Optional visibility
426        pub visibility: Option<Visibility>,
427        /// Field name
428        pub name: Ident,
429        /// Colon
430        pub _colon: Colon,
431        /// Field type (everything until comma or brace closing)
432        pub field_type: VerbatimUntil<Either<Comma, BraceGroup>>,
433    }
434
435    /// type Alias = Type;
436    #[derive(Clone)]
437    pub struct TypeAliasSig {
438        /// Optional attributes
439        pub attributes: Option<Many<Attribute>>,
440        /// Optional visibility
441        pub visibility: Option<Visibility>,
442        /// "type" keyword
443        pub _type: KType,
444        /// Alias name
445        pub name: Ident,
446        /// Optional generic parameters
447        pub generics: Option<Generics>,
448        /// Equals sign
449        pub _eq: Eq,
450        /// Target type (everything until semicolon)
451        pub target: VerbatimUntil<Semicolon>,
452        /// Semicolon
453        pub _semi: Semicolon,
454    }
455
456    /// const NAME: Type = value;
457    #[derive(Clone)]
458    pub struct ConstSig {
459        /// Optional attributes
460        pub attributes: Option<Many<Attribute>>,
461        /// Optional visibility
462        pub visibility: Option<Visibility>,
463        /// "const" keyword
464        pub _const: KConst,
465        /// Constant name
466        pub name: Ident,
467        /// Colon
468        pub _colon: Colon,
469        /// Type (everything until equals)
470        pub const_type: VerbatimUntil<Eq>,
471        /// Equals sign
472        pub _eq: Eq,
473        /// Value (everything until semicolon)
474        pub value: VerbatimUntil<Semicolon>,
475        /// Semicolon
476        pub _semi: Semicolon,
477    }
478
479    /// static NAME: Type = value;
480    #[derive(Clone)]
481    pub struct StaticSig {
482        /// Optional attributes
483        pub attributes: Option<Many<Attribute>>,
484        /// Optional visibility
485        pub visibility: Option<Visibility>,
486        /// "static" keyword
487        pub _static: KStatic,
488        /// Optional mut keyword
489        pub mut_kw: Option<KMut>,
490        /// Static name
491        pub name: Ident,
492        /// Colon
493        pub _colon: Colon,
494        /// Type (everything until equals)
495        pub static_type: VerbatimUntil<Eq>,
496        /// Equals sign
497        pub _eq: Eq,
498        /// Value (everything until semicolon)
499        pub value: VerbatimUntil<Semicolon>,
500        /// Semicolon
501        pub _semi: Semicolon,
502    }
503
504    /// Single enum variant
505    #[derive(Clone)]
506    pub struct EnumVariant {
507        /// Optional attributes
508        pub attributes: Option<Many<Attribute>>,
509        /// Variant name
510        pub name: Ident,
511        /// Optional variant data (fields or discriminant)
512        pub data: Option<EnumVariantData>,
513    }
514
515    /// Enum variant data
516    #[derive(Clone)]
517    pub enum EnumVariantData {
518        /// Tuple variant: (Type, Type)
519        Tuple(ParenthesisGroup),
520        /// Struct variant: { field: Type }
521        Struct(BraceGroupContaining<Option<CommaDelimitedVec<StructField>>>),
522        /// Discriminant: = value
523        Discriminant(Cons<Eq, VerbatimUntil<Either<Comma, BraceGroup>>>),
524    }
525
526    /// A complete module/file content
527    #[derive(Clone)]
528    pub struct ModuleContent {
529        /// Inner attributes at the top of the module (#![...])
530        pub inner_attrs: Option<Many<InnerAttribute>>,
531        /// All items in the module
532        pub items: Many<ModuleItem>,
533    }
534
535    /// Function parameter: name: Type or self variants
536    #[derive(Clone)]
537    pub enum FnParam {
538        /// self parameter
539        SelfParam(SelfParam),
540        /// Regular parameter: name: Type
541        Named(NamedParam),
542        /// Pattern parameter: (a, b): (i32, i32)
543        Pattern(PatternParam),
544    }
545
546    /// self, &self, &mut self, mut self
547    #[derive(Clone)]
548    pub enum SelfParam {
549        /// self
550        Value(KSelf),
551        /// &self
552        Ref(Cons<And, KSelf>),
553        /// &mut self
554        RefMut(Cons<And, Cons<KMut, KSelf>>),
555        /// mut self
556        Mut(Cons<KMut, KSelf>),
557    }
558
559    /// name: Type parameter
560    #[derive(Clone)]
561    pub struct NamedParam {
562        /// Optional mut keyword
563        pub mut_kw: Option<KMut>,
564        /// Parameter name
565        pub name: Ident,
566        /// Colon
567        pub _colon: Colon,
568        /// Parameter type (opaque for now)
569        pub param_type: VerbatimUntil<Comma>,
570    }
571
572    /// Pattern parameter like (a, b): (i32, i32) or mut (x, y): Point
573    #[derive(Clone)]
574    pub struct PatternParam {
575        /// Optional mut keyword
576        pub mut_kw: Option<KMut>,
577        /// Pattern (everything before colon, could be tuple, struct pattern, etc.)
578        pub pattern: Pattern,
579        /// Colon
580        pub _colon: Colon,
581        /// Parameter type
582        pub param_type: VerbatimUntil<Either<Comma, ParenthesisGroup>>,
583    }
584
585    /// Different types of patterns
586    #[derive(Clone)]
587    pub enum Pattern {
588        /// Simple identifier: value
589        Ident(Ident),
590        /// Tuple pattern: (a, b, c)
591        Tuple(TuplePattern),
592        /// Other patterns (fallback)
593        Other(VerbatimUntil<Colon>),
594    }
595
596    /// Tuple destructuring pattern: (a, b, c)
597    #[derive(Clone)]
598    pub struct TuplePattern {
599        /// Parentheses containing comma-separated identifiers
600        pub fields: ParenthesisGroupContaining<Option<CommaDelimitedVec<PatternField>>>,
601    }
602
603    /// Field in a pattern
604    #[derive(Clone)]
605    pub enum PatternField {
606        /// Simple identifier
607        Ident(Ident),
608        /// Nested pattern (recursive)
609        Nested(Pattern),
610    }
611}
612
613// Implement ToTokens for quote! compatibility
614impl quote::ToTokens for FnSig {
615    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
616        // Add attributes
617        if let Some(attrs) = &self.attributes {
618            for attr in &attrs.0 {
619                unsynn::ToTokens::to_tokens(attr, tokens);
620            }
621        }
622
623        // Add visibility
624        if let Some(vis) = &self.visibility {
625            quote::ToTokens::to_tokens(vis, tokens);
626        }
627
628        // Add const keyword
629        if let Some(const_kw) = &self.const_kw {
630            unsynn::ToTokens::to_tokens(const_kw, tokens);
631        }
632
633        // Add async keyword
634        if let Some(async_kw) = &self.async_kw {
635            unsynn::ToTokens::to_tokens(async_kw, tokens);
636        }
637
638        // Add unsafe keyword
639        if let Some(unsafe_kw) = &self.unsafe_kw {
640            unsynn::ToTokens::to_tokens(unsafe_kw, tokens);
641        }
642
643        // Add extern specification
644        if let Some(extern_kw) = &self.extern_kw {
645            unsynn::ToTokens::to_tokens(extern_kw, tokens);
646        }
647
648        // Add fn keyword and the rest
649        unsynn::ToTokens::to_tokens(&self._fn, tokens);
650        quote::ToTokens::to_tokens(&self.name, tokens);
651
652        if let Some(generics) = &self.generics {
653            unsynn::ToTokens::to_tokens(generics, tokens);
654        }
655
656        unsynn::ToTokens::to_tokens(&self.params, tokens);
657
658        if let Some(ret_type) = &self.return_type {
659            unsynn::ToTokens::to_tokens(ret_type, tokens);
660        }
661
662        if let Some(where_clause) = &self.where_clause {
663            unsynn::ToTokens::to_tokens(where_clause, tokens);
664        }
665
666        unsynn::ToTokens::to_tokens(&self.body, tokens);
667    }
668}
669
670impl quote::ToTokens for TraitMethodSig {
671    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
672        // Add attributes
673        if let Some(attrs) = &self.attributes {
674            for attr in &attrs.0 {
675                unsynn::ToTokens::to_tokens(attr, tokens);
676            }
677        }
678
679        // Add const keyword
680        if let Some(const_kw) = &self.const_kw {
681            unsynn::ToTokens::to_tokens(const_kw, tokens);
682        }
683
684        // Add async keyword
685        if let Some(async_kw) = &self.async_kw {
686            unsynn::ToTokens::to_tokens(async_kw, tokens);
687        }
688
689        // Add unsafe keyword
690        if let Some(unsafe_kw) = &self.unsafe_kw {
691            unsynn::ToTokens::to_tokens(unsafe_kw, tokens);
692        }
693
694        // Add extern specification
695        if let Some(extern_kw) = &self.extern_kw {
696            unsynn::ToTokens::to_tokens(extern_kw, tokens);
697        }
698
699        // Add fn keyword and the rest
700        unsynn::ToTokens::to_tokens(&self._fn, tokens);
701        quote::ToTokens::to_tokens(&self.name, tokens);
702
703        if let Some(generics) = &self.generics {
704            unsynn::ToTokens::to_tokens(generics, tokens);
705        }
706
707        unsynn::ToTokens::to_tokens(&self.params, tokens);
708
709        if let Some(ret_type) = &self.return_type {
710            unsynn::ToTokens::to_tokens(ret_type, tokens);
711        }
712
713        if let Some(where_clause) = &self.where_clause {
714            unsynn::ToTokens::to_tokens(where_clause, tokens);
715        }
716
717        unsynn::ToTokens::to_tokens(&self._semi, tokens);
718    }
719}
720
721impl quote::ToTokens for FnParam {
722    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
723        match self {
724            FnParam::SelfParam(self_param) => quote::ToTokens::to_tokens(self_param, tokens),
725            FnParam::Named(named) => quote::ToTokens::to_tokens(named, tokens),
726            FnParam::Pattern(pattern) => quote::ToTokens::to_tokens(pattern, tokens),
727        }
728    }
729}
730
731impl quote::ToTokens for SelfParam {
732    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
733        match self {
734            SelfParam::Value(self_kw) => unsynn::ToTokens::to_tokens(self_kw, tokens),
735            SelfParam::Ref(ref_self) => unsynn::ToTokens::to_tokens(ref_self, tokens),
736            SelfParam::RefMut(ref_mut_self) => unsynn::ToTokens::to_tokens(ref_mut_self, tokens),
737            SelfParam::Mut(mut_self) => unsynn::ToTokens::to_tokens(mut_self, tokens),
738        }
739    }
740}
741
742impl quote::ToTokens for NamedParam {
743    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
744        if let Some(mut_kw) = &self.mut_kw {
745            unsynn::ToTokens::to_tokens(mut_kw, tokens);
746        }
747        quote::ToTokens::to_tokens(&self.name, tokens);
748        unsynn::ToTokens::to_tokens(&self._colon, tokens);
749        unsynn::ToTokens::to_tokens(&self.param_type, tokens);
750    }
751}
752
753impl quote::ToTokens for PatternParam {
754    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
755        if let Some(mut_kw) = &self.mut_kw {
756            unsynn::ToTokens::to_tokens(mut_kw, tokens);
757        }
758        unsynn::ToTokens::to_tokens(&self.pattern, tokens);
759        unsynn::ToTokens::to_tokens(&self._colon, tokens);
760        unsynn::ToTokens::to_tokens(&self.param_type, tokens);
761    }
762}
763
764impl quote::ToTokens for Pattern {
765    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
766        match self {
767            Pattern::Tuple(tuple) => quote::ToTokens::to_tokens(tuple, tokens),
768            Pattern::Ident(ident) => quote::ToTokens::to_tokens(ident, tokens),
769            Pattern::Other(other) => unsynn::ToTokens::to_tokens(other, tokens),
770        }
771    }
772}
773
774impl quote::ToTokens for TuplePattern {
775    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
776        unsynn::ToTokens::to_tokens(&self.fields, tokens);
777    }
778}
779
780impl quote::ToTokens for PatternField {
781    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
782        match self {
783            PatternField::Ident(ident) => quote::ToTokens::to_tokens(ident, tokens),
784            PatternField::Nested(pattern) => quote::ToTokens::to_tokens(pattern, tokens),
785        }
786    }
787}
788
789impl quote::ToTokens for Visibility {
790    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
791        match self {
792            Visibility::Public(pub_kw) => unsynn::ToTokens::to_tokens(pub_kw, tokens),
793            Visibility::Restricted(restricted) => unsynn::ToTokens::to_tokens(restricted, tokens),
794        }
795    }
796}
797
798impl quote::ToTokens for ExternSpec {
799    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
800        match self {
801            ExternSpec::WithAbi(with_abi) => unsynn::ToTokens::to_tokens(with_abi, tokens),
802            ExternSpec::Bare(extern_kw) => unsynn::ToTokens::to_tokens(extern_kw, tokens),
803        }
804    }
805}
806
807impl quote::ToTokens for ReturnTypeTrait {
808    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
809        unsynn::ToTokens::to_tokens(&self._arrow, tokens);
810        unsynn::ToTokens::to_tokens(&self.return_type, tokens);
811    }
812}
813
814impl quote::ToTokens for ReturnTypeFn {
815    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
816        unsynn::ToTokens::to_tokens(&self._arrow, tokens);
817        unsynn::ToTokens::to_tokens(&self.return_type, tokens);
818    }
819}
820
821impl quote::ToTokens for Generics {
822    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
823        unsynn::ToTokens::to_tokens(&self._lt, tokens);
824        unsynn::ToTokens::to_tokens(&self.content, tokens);
825        unsynn::ToTokens::to_tokens(&self._gt, tokens);
826    }
827}
828
829impl quote::ToTokens for WhereClause {
830    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
831        unsynn::ToTokens::to_tokens(&self._pred, tokens);
832        unsynn::ToTokens::to_tokens(&self._colon, tokens);
833        unsynn::ToTokens::to_tokens(&self.bounds, tokens);
834    }
835}
836
837impl quote::ToTokens for WhereClauses {
838    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
839        unsynn::ToTokens::to_tokens(&self._kw_where, tokens);
840        unsynn::ToTokens::to_tokens(&self.clauses, tokens);
841    }
842}
843
844impl quote::ToTokens for Attribute {
845    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
846        unsynn::ToTokens::to_tokens(&self._hash, tokens);
847        unsynn::ToTokens::to_tokens(&self.content, tokens);
848    }
849}
850
851impl quote::ToTokens for InnerAttribute {
852    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
853        unsynn::ToTokens::to_tokens(&self._hash, tokens);
854        unsynn::ToTokens::to_tokens(&self._bang, tokens);
855        unsynn::ToTokens::to_tokens(&self.content, tokens);
856    }
857}
858
859impl quote::ToTokens for AnyAttribute {
860    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
861        match self {
862            AnyAttribute::Inner(inner) => quote::ToTokens::to_tokens(inner, tokens),
863            AnyAttribute::Outer(outer) => quote::ToTokens::to_tokens(outer, tokens),
864        }
865    }
866}
867
868impl quote::ToTokens for RestrictedVis {
869    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
870        unsynn::ToTokens::to_tokens(&self._pub, tokens);
871        unsynn::ToTokens::to_tokens(&self.restriction, tokens);
872    }
873}
874
875impl quote::ToTokens for ExternWithAbi {
876    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
877        unsynn::ToTokens::to_tokens(&self._extern, tokens);
878        unsynn::ToTokens::to_tokens(&self.abi, tokens);
879    }
880}
881
882impl quote::ToTokens for ModuleItem {
883    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
884        match self {
885            ModuleItem::TraitMethod(method) => quote::ToTokens::to_tokens(method, tokens),
886            ModuleItem::Function(func) => quote::ToTokens::to_tokens(func, tokens),
887            ModuleItem::ImplBlock(impl_block) => quote::ToTokens::to_tokens(impl_block, tokens),
888            ModuleItem::Module(module) => quote::ToTokens::to_tokens(module, tokens),
889            ModuleItem::Trait(trait_def) => quote::ToTokens::to_tokens(trait_def, tokens),
890            ModuleItem::Enum(enum_sig) => quote::ToTokens::to_tokens(enum_sig, tokens),
891            ModuleItem::Struct(struct_sig) => quote::ToTokens::to_tokens(struct_sig, tokens),
892            ModuleItem::TypeAlias(type_alias) => quote::ToTokens::to_tokens(type_alias, tokens),
893            ModuleItem::Const(const_sig) => quote::ToTokens::to_tokens(const_sig, tokens),
894            ModuleItem::Static(static_sig) => quote::ToTokens::to_tokens(static_sig, tokens),
895            ModuleItem::Other(token_tree) => unsynn::ToTokens::to_tokens(token_tree, tokens),
896        }
897    }
898}
899
900impl quote::ToTokens for ImplBlockSig {
901    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
902        if let Some(attrs) = &self.attributes {
903            for attr in &attrs.0 {
904                unsynn::ToTokens::to_tokens(attr, tokens);
905            }
906        }
907        unsynn::ToTokens::to_tokens(&self._impl, tokens);
908        if let Some(generics) = &self.generics {
909            unsynn::ToTokens::to_tokens(generics, tokens);
910        }
911        unsynn::ToTokens::to_tokens(&self.target_type, tokens);
912        if let Some(for_trait) = &self.for_trait {
913            unsynn::ToTokens::to_tokens(for_trait, tokens);
914        }
915        if let Some(where_clause) = &self.where_clause {
916            unsynn::ToTokens::to_tokens(where_clause, tokens);
917        }
918        unsynn::ToTokens::to_tokens(&self.items, tokens);
919    }
920}
921
922impl quote::ToTokens for ModuleSig {
923    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
924        if let Some(attrs) = &self.attributes {
925            for attr in &attrs.0 {
926                unsynn::ToTokens::to_tokens(attr, tokens);
927            }
928        }
929        if let Some(vis) = &self.visibility {
930            quote::ToTokens::to_tokens(vis, tokens);
931        }
932        unsynn::ToTokens::to_tokens(&self._mod, tokens);
933        quote::ToTokens::to_tokens(&self.name, tokens);
934        unsynn::ToTokens::to_tokens(&self.items, tokens);
935    }
936}
937
938impl quote::ToTokens for TraitSig {
939    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
940        if let Some(attrs) = &self.attributes {
941            for attr in &attrs.0 {
942                unsynn::ToTokens::to_tokens(attr, tokens);
943            }
944        }
945        if let Some(vis) = &self.visibility {
946            quote::ToTokens::to_tokens(vis, tokens);
947        }
948        if let Some(unsafe_kw) = &self.unsafe_kw {
949            unsynn::ToTokens::to_tokens(unsafe_kw, tokens);
950        }
951        unsynn::ToTokens::to_tokens(&self._trait, tokens);
952        quote::ToTokens::to_tokens(&self.name, tokens);
953        if let Some(generics) = &self.generics {
954            unsynn::ToTokens::to_tokens(generics, tokens);
955        }
956        if let Some(bounds) = &self.bounds {
957            unsynn::ToTokens::to_tokens(bounds, tokens);
958        }
959        if let Some(where_clause) = &self.where_clause {
960            unsynn::ToTokens::to_tokens(where_clause, tokens);
961        }
962        unsynn::ToTokens::to_tokens(&self.items, tokens);
963    }
964}
965
966impl quote::ToTokens for ModuleContent {
967    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
968        // Output inner attributes first
969        if let Some(inner_attrs) = &self.inner_attrs {
970            for attr_delimited in &inner_attrs.0 {
971                quote::ToTokens::to_tokens(&attr_delimited.value, tokens);
972            }
973        }
974        unsynn::ToTokens::to_tokens(&self.items, tokens);
975    }
976}
977
978impl quote::ToTokens for EnumSig {
979    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
980        if let Some(attrs) = &self.attributes {
981            for attr in &attrs.0 {
982                unsynn::ToTokens::to_tokens(attr, tokens);
983            }
984        }
985        if let Some(vis) = &self.visibility {
986            quote::ToTokens::to_tokens(vis, tokens);
987        }
988        unsynn::ToTokens::to_tokens(&self._enum, tokens);
989        quote::ToTokens::to_tokens(&self.name, tokens);
990        if let Some(generics) = &self.generics {
991            unsynn::ToTokens::to_tokens(generics, tokens);
992        }
993        if let Some(where_clause) = &self.where_clause {
994            unsynn::ToTokens::to_tokens(where_clause, tokens);
995        }
996        unsynn::ToTokens::to_tokens(&self.variants, tokens);
997    }
998}
999
1000impl quote::ToTokens for StructSig {
1001    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1002        if let Some(attrs) = &self.attributes {
1003            for attr in &attrs.0 {
1004                unsynn::ToTokens::to_tokens(attr, tokens);
1005            }
1006        }
1007        if let Some(vis) = &self.visibility {
1008            quote::ToTokens::to_tokens(vis, tokens);
1009        }
1010        unsynn::ToTokens::to_tokens(&self._struct, tokens);
1011        quote::ToTokens::to_tokens(&self.name, tokens);
1012        if let Some(generics) = &self.generics {
1013            unsynn::ToTokens::to_tokens(generics, tokens);
1014        }
1015        if let Some(where_clause) = &self.where_clause {
1016            unsynn::ToTokens::to_tokens(where_clause, tokens);
1017        }
1018        quote::ToTokens::to_tokens(&self.body, tokens);
1019    }
1020}
1021
1022impl quote::ToTokens for StructBody {
1023    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1024        match self {
1025            StructBody::Named(fields) => unsynn::ToTokens::to_tokens(fields, tokens),
1026            StructBody::Tuple(tuple) => unsynn::ToTokens::to_tokens(tuple, tokens),
1027            StructBody::Unit(semi) => unsynn::ToTokens::to_tokens(semi, tokens),
1028        }
1029    }
1030}
1031
1032impl quote::ToTokens for StructField {
1033    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1034        if let Some(attrs) = &self.attributes {
1035            for attr in &attrs.0 {
1036                unsynn::ToTokens::to_tokens(attr, tokens);
1037            }
1038        }
1039        if let Some(vis) = &self.visibility {
1040            quote::ToTokens::to_tokens(vis, tokens);
1041        }
1042        quote::ToTokens::to_tokens(&self.name, tokens);
1043        unsynn::ToTokens::to_tokens(&self._colon, tokens);
1044        unsynn::ToTokens::to_tokens(&self.field_type, tokens);
1045    }
1046}
1047
1048impl quote::ToTokens for TypeAliasSig {
1049    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1050        if let Some(attrs) = &self.attributes {
1051            for attr in &attrs.0 {
1052                unsynn::ToTokens::to_tokens(attr, tokens);
1053            }
1054        }
1055        if let Some(vis) = &self.visibility {
1056            quote::ToTokens::to_tokens(vis, tokens);
1057        }
1058        unsynn::ToTokens::to_tokens(&self._type, tokens);
1059        quote::ToTokens::to_tokens(&self.name, tokens);
1060        if let Some(generics) = &self.generics {
1061            unsynn::ToTokens::to_tokens(generics, tokens);
1062        }
1063        unsynn::ToTokens::to_tokens(&self._eq, tokens);
1064        unsynn::ToTokens::to_tokens(&self.target, tokens);
1065        unsynn::ToTokens::to_tokens(&self._semi, tokens);
1066    }
1067}
1068
1069impl quote::ToTokens for ConstSig {
1070    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1071        if let Some(attrs) = &self.attributes {
1072            for attr in &attrs.0 {
1073                unsynn::ToTokens::to_tokens(attr, tokens);
1074            }
1075        }
1076        if let Some(vis) = &self.visibility {
1077            quote::ToTokens::to_tokens(vis, tokens);
1078        }
1079        unsynn::ToTokens::to_tokens(&self._const, tokens);
1080        quote::ToTokens::to_tokens(&self.name, tokens);
1081        unsynn::ToTokens::to_tokens(&self._colon, tokens);
1082        unsynn::ToTokens::to_tokens(&self.const_type, tokens);
1083        unsynn::ToTokens::to_tokens(&self._eq, tokens);
1084        unsynn::ToTokens::to_tokens(&self.value, tokens);
1085        unsynn::ToTokens::to_tokens(&self._semi, tokens);
1086    }
1087}
1088
1089impl quote::ToTokens for StaticSig {
1090    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1091        if let Some(attrs) = &self.attributes {
1092            for attr in &attrs.0 {
1093                unsynn::ToTokens::to_tokens(attr, tokens);
1094            }
1095        }
1096        if let Some(vis) = &self.visibility {
1097            quote::ToTokens::to_tokens(vis, tokens);
1098        }
1099        if let Some(mut_kw) = &self.mut_kw {
1100            unsynn::ToTokens::to_tokens(mut_kw, tokens);
1101        }
1102        unsynn::ToTokens::to_tokens(&self._static, tokens);
1103        quote::ToTokens::to_tokens(&self.name, tokens);
1104        unsynn::ToTokens::to_tokens(&self._colon, tokens);
1105        unsynn::ToTokens::to_tokens(&self.static_type, tokens);
1106        unsynn::ToTokens::to_tokens(&self._eq, tokens);
1107        unsynn::ToTokens::to_tokens(&self.value, tokens);
1108        unsynn::ToTokens::to_tokens(&self._semi, tokens);
1109    }
1110}
1111
1112impl quote::ToTokens for EnumVariant {
1113    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1114        if let Some(attrs) = &self.attributes {
1115            for attr in &attrs.0 {
1116                unsynn::ToTokens::to_tokens(attr, tokens);
1117            }
1118        }
1119        quote::ToTokens::to_tokens(&self.name, tokens);
1120        if let Some(data) = &self.data {
1121            quote::ToTokens::to_tokens(data, tokens);
1122        }
1123    }
1124}
1125
1126impl quote::ToTokens for EnumVariantData {
1127    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1128        match self {
1129            EnumVariantData::Tuple(paren) => unsynn::ToTokens::to_tokens(paren, tokens),
1130            EnumVariantData::Struct(brace) => unsynn::ToTokens::to_tokens(brace, tokens),
1131            EnumVariantData::Discriminant(disc) => unsynn::ToTokens::to_tokens(disc, tokens),
1132        }
1133    }
1134}
1135
1136#[cfg(test)]
1137#[path = "tests/parse.rs"]
1138mod tests;