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<ReturnType>,
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    /// Return type: -> Type
210    #[derive(Clone)]
211    pub struct ReturnType {
212        /// Arrow
213        pub _arrow: RArrow,
214        /// Everything until brace (opaque)
215        pub return_type: VerbatimUntil<BraceGroup>,
216    }
217
218    /// Represents a single predicate within a `where` clause.
219    #[derive(Clone)]
220    pub struct WhereClause {
221        /// The type or lifetime being constrained (e.g., `T` or `'a`).
222        pub _pred: VerbatimUntil<Colon>,
223        /// The colon separating the constrained item and its bounds.
224        pub _colon: Colon,
225        /// The bounds applied to the type or lifetime (e.g., `Trait` or `'b`).
226        pub bounds: VerbatimUntil<Either<Comma, Semicolon, BraceGroup>>,
227    }
228
229    /// Where clauses: where T: Trait, U: Send
230    #[derive(Clone)]
231    pub struct WhereClauses {
232        /// The `where` keyword.
233        pub _kw_where: KWhere,
234        /// The comma-delimited list of where clause predicates.
235        pub clauses: CommaDelimitedVec<WhereClausePredicate>,
236    }
237
238    /// Single where clause predicate: T: Trait
239    #[derive(Clone)]
240    pub struct WhereClausePredicate {
241        /// The type being constrained (e.g., `T`)
242        pub pred: VerbatimUntil<Colon>,
243        /// The colon
244        pub _colon: Colon,
245        /// The bounds (e.g., `Trait`)
246        pub bounds: VerbatimUntil<Either<Comma, BraceGroup>>,
247    }
248
249    /// Top-level item that can appear in a module
250    #[derive(Clone)]
251    pub enum ModuleItem {
252        /// A function definition
253        Function(FnSig),
254        /// An impl block
255        ImplBlock(ImplBlockSig),
256        /// A module definition
257        Module(ModuleSig),
258        /// A trait definition
259        Trait(TraitSig),
260        /// An enum definition
261        Enum(EnumSig),
262        /// A struct definition
263        Struct(StructSig),
264        /// A type alias
265        TypeAlias(TypeAliasSig),
266        /// A constant
267        Const(ConstSig),
268        /// A static
269        Static(StaticSig),
270        /// Any other item (use, extern crate, etc.)
271        Other(TokenTree),
272    }
273
274    /// impl Type { ... } block
275    #[derive(Clone)]
276    pub struct ImplBlockSig {
277        /// Optional attributes
278        pub attributes: Option<Many<Attribute>>,
279        /// "impl" keyword
280        pub _impl: KImpl,
281        /// Optional generic parameters
282        pub generics: Option<Generics>,
283        /// Type being implemented (opaque for now)
284        pub target_type: Many<Cons<Except<Either<KFor, BraceGroup>>, TokenTree>>,
285        /// Optional "for Trait" part
286        pub for_trait: Option<Cons<KFor, Many<Cons<Except<BraceGroup>, TokenTree>>>>,
287        /// Optional where clause
288        pub where_clause: Option<WhereClauses>,
289        /// Parsed impl block contents
290        pub items: BraceGroupContaining<ModuleContent>,
291    }
292
293    /// mod name { ... } block
294    #[derive(Clone)]
295    pub struct ModuleSig {
296        /// Optional attributes
297        pub attributes: Option<Many<Attribute>>,
298        /// Optional visibility
299        pub visibility: Option<Visibility>,
300        /// "mod" keyword
301        pub _mod: KMod,
302        /// Module name
303        pub name: Ident,
304        /// Parsed module contents
305        pub items: BraceGroupContaining<ModuleContent>,
306    }
307
308    /// trait Name { ... } block
309    #[derive(Clone)]
310    pub struct TraitSig {
311        /// Optional attributes
312        pub attributes: Option<Many<Attribute>>,
313        /// Optional visibility
314        pub visibility: Option<Visibility>,
315        /// Optional unsafe
316        pub unsafe_kw: Option<KUnsafe>,
317        /// "trait" keyword
318        pub _trait: KTrait,
319        /// Trait name
320        pub name: Ident,
321        /// Optional generic parameters
322        pub generics: Option<Generics>,
323        /// Optional trait bounds
324        pub bounds: Option<Cons<Colon, Many<Cons<Except<Either<KWhere, BraceGroup>>, TokenTree>>>>,
325        /// Optional where clause
326        pub where_clause: Option<WhereClauses>,
327        /// Parsed trait body
328        pub items: BraceGroupContaining<ModuleContent>,
329    }
330
331    /// enum Name { ... } block
332    #[derive(Clone)]
333    pub struct EnumSig {
334        /// Optional attributes
335        pub attributes: Option<Many<Attribute>>,
336        /// Optional visibility
337        pub visibility: Option<Visibility>,
338        /// "enum" keyword
339        pub _enum: KEnum,
340        /// Enum name
341        pub name: Ident,
342        /// Optional generic parameters
343        pub generics: Option<Generics>,
344        /// Optional where clause
345        pub where_clause: Option<WhereClauses>,
346        /// Parsed enum variants
347        pub variants: BraceGroupContaining<Option<CommaDelimitedVec<EnumVariant>>>,
348    }
349
350    /// struct Name { ... } or struct Name;
351    #[derive(Clone)]
352    pub struct StructSig {
353        /// Optional attributes
354        pub attributes: Option<Many<Attribute>>,
355        /// Optional visibility
356        pub visibility: Option<Visibility>,
357        /// "struct" keyword
358        pub _struct: KStruct,
359        /// Struct name
360        pub name: Ident,
361        /// Optional generic parameters
362        pub generics: Option<Generics>,
363        /// Optional where clause
364        pub where_clause: Option<WhereClauses>,
365        /// Struct body (could be brace group, tuple, or unit)
366        pub body: StructBody,
367    }
368
369    /// Struct body variants
370    #[derive(Clone)]
371    pub enum StructBody {
372        /// Named fields with parsed field list
373        Named(BraceGroupContaining<Option<CommaDelimitedVec<StructField>>>),
374        /// Tuple fields: (Type, Type)
375        Tuple(Cons<ParenthesisGroup, Semicolon>),
376        /// Unit struct: ;
377        Unit(Semicolon),
378    }
379
380    /// Named struct field: pub name: Type
381    #[derive(Clone)]
382    pub struct StructField {
383        /// Optional attributes
384        pub attributes: Option<Many<Attribute>>,
385        /// Optional visibility
386        pub visibility: Option<Visibility>,
387        /// Field name
388        pub name: Ident,
389        /// Colon
390        pub _colon: Colon,
391        /// Field type (everything until comma or brace closing)
392        pub field_type: VerbatimUntil<Either<Comma, BraceGroup>>,
393    }
394
395    /// type Alias = Type;
396    #[derive(Clone)]
397    pub struct TypeAliasSig {
398        /// Optional attributes
399        pub attributes: Option<Many<Attribute>>,
400        /// Optional visibility
401        pub visibility: Option<Visibility>,
402        /// "type" keyword
403        pub _type: KType,
404        /// Alias name
405        pub name: Ident,
406        /// Optional generic parameters
407        pub generics: Option<Generics>,
408        /// Equals sign
409        pub _eq: Eq,
410        /// Target type (everything until semicolon)
411        pub target: VerbatimUntil<Semicolon>,
412        /// Semicolon
413        pub _semi: Semicolon,
414    }
415
416    /// const NAME: Type = value;
417    #[derive(Clone)]
418    pub struct ConstSig {
419        /// Optional attributes
420        pub attributes: Option<Many<Attribute>>,
421        /// Optional visibility
422        pub visibility: Option<Visibility>,
423        /// "const" keyword
424        pub _const: KConst,
425        /// Constant name
426        pub name: Ident,
427        /// Colon
428        pub _colon: Colon,
429        /// Type (everything until equals)
430        pub const_type: VerbatimUntil<Eq>,
431        /// Equals sign
432        pub _eq: Eq,
433        /// Value (everything until semicolon)
434        pub value: VerbatimUntil<Semicolon>,
435        /// Semicolon
436        pub _semi: Semicolon,
437    }
438
439    /// static NAME: Type = value;
440    #[derive(Clone)]
441    pub struct StaticSig {
442        /// Optional attributes
443        pub attributes: Option<Many<Attribute>>,
444        /// Optional visibility
445        pub visibility: Option<Visibility>,
446        /// Optional mut keyword
447        pub mut_kw: Option<KMut>,
448        /// "static" keyword
449        pub _static: KStatic,
450        /// Static name
451        pub name: Ident,
452        /// Colon
453        pub _colon: Colon,
454        /// Type (everything until equals)
455        pub static_type: VerbatimUntil<Eq>,
456        /// Equals sign
457        pub _eq: Eq,
458        /// Value (everything until semicolon)
459        pub value: VerbatimUntil<Semicolon>,
460        /// Semicolon
461        pub _semi: Semicolon,
462    }
463
464    /// Single enum variant
465    #[derive(Clone)]
466    pub struct EnumVariant {
467        /// Optional attributes
468        pub attributes: Option<Many<Attribute>>,
469        /// Variant name
470        pub name: Ident,
471        /// Optional variant data (fields or discriminant)
472        pub data: Option<EnumVariantData>,
473    }
474
475    /// Enum variant data
476    #[derive(Clone)]
477    pub enum EnumVariantData {
478        /// Tuple variant: (Type, Type)
479        Tuple(ParenthesisGroup),
480        /// Struct variant: { field: Type }
481        Struct(BraceGroupContaining<Option<CommaDelimitedVec<StructField>>>),
482        /// Discriminant: = value
483        Discriminant(Cons<Eq, VerbatimUntil<Either<Comma, BraceGroup>>>),
484    }
485
486    /// A complete module/file content
487    #[derive(Clone)]
488    pub struct ModuleContent {
489        /// Inner attributes at the top of the module (#![...])
490        pub inner_attrs: Option<Many<InnerAttribute>>,
491        /// All items in the module
492        pub items: Many<ModuleItem>,
493    }
494
495    /// Function parameter: name: Type or self variants
496    #[derive(Clone)]
497    pub enum FnParam {
498        /// self parameter
499        SelfParam(SelfParam),
500        /// Regular parameter: name: Type
501        Named(NamedParam),
502        /// Pattern parameter: (a, b): (i32, i32)
503        Pattern(PatternParam),
504    }
505
506    /// self, &self, &mut self, mut self
507    #[derive(Clone)]
508    pub enum SelfParam {
509        /// self
510        Value(KSelf),
511        /// &self
512        Ref(Cons<And, KSelf>),
513        /// &mut self
514        RefMut(Cons<And, Cons<KMut, KSelf>>),
515        /// mut self
516        Mut(Cons<KMut, KSelf>),
517    }
518
519    /// name: Type parameter
520    #[derive(Clone)]
521    pub struct NamedParam {
522        /// Optional mut keyword
523        pub mut_kw: Option<KMut>,
524        /// Parameter name
525        pub name: Ident,
526        /// Colon
527        pub _colon: Colon,
528        /// Parameter type (opaque for now)
529        pub param_type: VerbatimUntil<Comma>,
530    }
531
532    /// Pattern parameter like (a, b): (i32, i32) or mut (x, y): Point
533    #[derive(Clone)]
534    pub struct PatternParam {
535        /// Optional mut keyword
536        pub mut_kw: Option<KMut>,
537        /// Pattern (everything before colon, could be tuple, struct pattern, etc.)
538        pub pattern: Pattern,
539        /// Colon
540        pub _colon: Colon,
541        /// Parameter type
542        pub param_type: VerbatimUntil<Either<Comma, ParenthesisGroup>>,
543    }
544
545    /// Different types of patterns
546    #[derive(Clone)]
547    pub enum Pattern {
548        /// Simple identifier: value
549        Ident(Ident),
550        /// Tuple pattern: (a, b, c)
551        Tuple(TuplePattern),
552        /// Other patterns (fallback)
553        Other(VerbatimUntil<Colon>),
554    }
555
556    /// Tuple destructuring pattern: (a, b, c)
557    #[derive(Clone)]
558    pub struct TuplePattern {
559        /// Parentheses containing comma-separated identifiers
560        pub fields: ParenthesisGroupContaining<Option<CommaDelimitedVec<PatternField>>>,
561    }
562
563    /// Field in a pattern
564    #[derive(Clone)]
565    pub enum PatternField {
566        /// Simple identifier
567        Ident(Ident),
568        /// Nested pattern (recursive)
569        Nested(Pattern),
570    }
571}
572
573// Implement ToTokens for quote! compatibility
574impl quote::ToTokens for FnSig {
575    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
576        // Add attributes
577        if let Some(attrs) = &self.attributes {
578            for attr in &attrs.0 {
579                unsynn::ToTokens::to_tokens(attr, tokens);
580            }
581        }
582
583        // Add visibility
584        if let Some(vis) = &self.visibility {
585            quote::ToTokens::to_tokens(vis, tokens);
586        }
587
588        // Add const keyword
589        if let Some(const_kw) = &self.const_kw {
590            unsynn::ToTokens::to_tokens(const_kw, tokens);
591        }
592
593        // Add async keyword
594        if let Some(async_kw) = &self.async_kw {
595            unsynn::ToTokens::to_tokens(async_kw, tokens);
596        }
597
598        // Add unsafe keyword
599        if let Some(unsafe_kw) = &self.unsafe_kw {
600            unsynn::ToTokens::to_tokens(unsafe_kw, tokens);
601        }
602
603        // Add extern specification
604        if let Some(extern_kw) = &self.extern_kw {
605            unsynn::ToTokens::to_tokens(extern_kw, tokens);
606        }
607
608        // Add fn keyword and the rest
609        unsynn::ToTokens::to_tokens(&self._fn, tokens);
610        quote::ToTokens::to_tokens(&self.name, tokens);
611
612        if let Some(generics) = &self.generics {
613            unsynn::ToTokens::to_tokens(generics, tokens);
614        }
615
616        unsynn::ToTokens::to_tokens(&self.params, tokens);
617
618        if let Some(ret_type) = &self.return_type {
619            unsynn::ToTokens::to_tokens(ret_type, tokens);
620        }
621
622        if let Some(where_clause) = &self.where_clause {
623            unsynn::ToTokens::to_tokens(where_clause, tokens);
624        }
625
626        unsynn::ToTokens::to_tokens(&self.body, tokens);
627    }
628}
629
630impl quote::ToTokens for FnParam {
631    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
632        match self {
633            FnParam::SelfParam(self_param) => quote::ToTokens::to_tokens(self_param, tokens),
634            FnParam::Named(named) => quote::ToTokens::to_tokens(named, tokens),
635            FnParam::Pattern(pattern) => quote::ToTokens::to_tokens(pattern, tokens),
636        }
637    }
638}
639
640impl quote::ToTokens for SelfParam {
641    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
642        match self {
643            SelfParam::Value(self_kw) => unsynn::ToTokens::to_tokens(self_kw, tokens),
644            SelfParam::Ref(ref_self) => unsynn::ToTokens::to_tokens(ref_self, tokens),
645            SelfParam::RefMut(ref_mut_self) => unsynn::ToTokens::to_tokens(ref_mut_self, tokens),
646            SelfParam::Mut(mut_self) => unsynn::ToTokens::to_tokens(mut_self, tokens),
647        }
648    }
649}
650
651impl quote::ToTokens for NamedParam {
652    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
653        if let Some(mut_kw) = &self.mut_kw {
654            unsynn::ToTokens::to_tokens(mut_kw, tokens);
655        }
656        quote::ToTokens::to_tokens(&self.name, tokens);
657        unsynn::ToTokens::to_tokens(&self._colon, tokens);
658        unsynn::ToTokens::to_tokens(&self.param_type, tokens);
659    }
660}
661
662impl quote::ToTokens for PatternParam {
663    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
664        if let Some(mut_kw) = &self.mut_kw {
665            unsynn::ToTokens::to_tokens(mut_kw, tokens);
666        }
667        unsynn::ToTokens::to_tokens(&self.pattern, tokens);
668        unsynn::ToTokens::to_tokens(&self._colon, tokens);
669        unsynn::ToTokens::to_tokens(&self.param_type, tokens);
670    }
671}
672
673impl quote::ToTokens for Pattern {
674    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
675        match self {
676            Pattern::Tuple(tuple) => quote::ToTokens::to_tokens(tuple, tokens),
677            Pattern::Ident(ident) => quote::ToTokens::to_tokens(ident, tokens),
678            Pattern::Other(other) => unsynn::ToTokens::to_tokens(other, tokens),
679        }
680    }
681}
682
683impl quote::ToTokens for TuplePattern {
684    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
685        unsynn::ToTokens::to_tokens(&self.fields, tokens);
686    }
687}
688
689impl quote::ToTokens for PatternField {
690    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
691        match self {
692            PatternField::Ident(ident) => quote::ToTokens::to_tokens(ident, tokens),
693            PatternField::Nested(pattern) => quote::ToTokens::to_tokens(pattern, tokens),
694        }
695    }
696}
697
698impl quote::ToTokens for Visibility {
699    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
700        match self {
701            Visibility::Public(pub_kw) => unsynn::ToTokens::to_tokens(pub_kw, tokens),
702            Visibility::Restricted(restricted) => unsynn::ToTokens::to_tokens(restricted, tokens),
703        }
704    }
705}
706
707impl quote::ToTokens for ExternSpec {
708    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
709        match self {
710            ExternSpec::WithAbi(with_abi) => unsynn::ToTokens::to_tokens(with_abi, tokens),
711            ExternSpec::Bare(extern_kw) => unsynn::ToTokens::to_tokens(extern_kw, tokens),
712        }
713    }
714}
715
716impl quote::ToTokens for ReturnType {
717    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
718        unsynn::ToTokens::to_tokens(&self._arrow, tokens);
719        unsynn::ToTokens::to_tokens(&self.return_type, tokens);
720    }
721}
722
723impl quote::ToTokens for Generics {
724    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
725        unsynn::ToTokens::to_tokens(&self._lt, tokens);
726        unsynn::ToTokens::to_tokens(&self.content, tokens);
727        unsynn::ToTokens::to_tokens(&self._gt, tokens);
728    }
729}
730
731impl quote::ToTokens for WhereClause {
732    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
733        unsynn::ToTokens::to_tokens(&self._pred, tokens);
734        unsynn::ToTokens::to_tokens(&self._colon, tokens);
735        unsynn::ToTokens::to_tokens(&self.bounds, tokens);
736    }
737}
738
739impl quote::ToTokens for WhereClauses {
740    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
741        unsynn::ToTokens::to_tokens(&self._kw_where, tokens);
742        unsynn::ToTokens::to_tokens(&self.clauses, tokens);
743    }
744}
745
746impl quote::ToTokens for Attribute {
747    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
748        unsynn::ToTokens::to_tokens(&self._hash, tokens);
749        unsynn::ToTokens::to_tokens(&self.content, tokens);
750    }
751}
752
753impl quote::ToTokens for InnerAttribute {
754    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
755        unsynn::ToTokens::to_tokens(&self._hash, tokens);
756        unsynn::ToTokens::to_tokens(&self._bang, tokens);
757        unsynn::ToTokens::to_tokens(&self.content, tokens);
758    }
759}
760
761impl quote::ToTokens for AnyAttribute {
762    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
763        match self {
764            AnyAttribute::Inner(inner) => quote::ToTokens::to_tokens(inner, tokens),
765            AnyAttribute::Outer(outer) => quote::ToTokens::to_tokens(outer, tokens),
766        }
767    }
768}
769
770impl quote::ToTokens for RestrictedVis {
771    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
772        unsynn::ToTokens::to_tokens(&self._pub, tokens);
773        unsynn::ToTokens::to_tokens(&self.restriction, tokens);
774    }
775}
776
777impl quote::ToTokens for ExternWithAbi {
778    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
779        unsynn::ToTokens::to_tokens(&self._extern, tokens);
780        unsynn::ToTokens::to_tokens(&self.abi, tokens);
781    }
782}
783
784impl quote::ToTokens for ModuleItem {
785    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
786        match self {
787            ModuleItem::Function(func) => quote::ToTokens::to_tokens(func, tokens),
788            ModuleItem::ImplBlock(impl_block) => quote::ToTokens::to_tokens(impl_block, tokens),
789            ModuleItem::Module(module) => quote::ToTokens::to_tokens(module, tokens),
790            ModuleItem::Trait(trait_def) => quote::ToTokens::to_tokens(trait_def, tokens),
791            ModuleItem::Enum(enum_sig) => quote::ToTokens::to_tokens(enum_sig, tokens),
792            ModuleItem::Struct(struct_sig) => quote::ToTokens::to_tokens(struct_sig, tokens),
793            ModuleItem::TypeAlias(type_alias) => quote::ToTokens::to_tokens(type_alias, tokens),
794            ModuleItem::Const(const_sig) => quote::ToTokens::to_tokens(const_sig, tokens),
795            ModuleItem::Static(static_sig) => quote::ToTokens::to_tokens(static_sig, tokens),
796            ModuleItem::Other(token_tree) => unsynn::ToTokens::to_tokens(token_tree, tokens),
797        }
798    }
799}
800
801impl quote::ToTokens for ImplBlockSig {
802    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
803        if let Some(attrs) = &self.attributes {
804            for attr in &attrs.0 {
805                unsynn::ToTokens::to_tokens(attr, tokens);
806            }
807        }
808        unsynn::ToTokens::to_tokens(&self._impl, tokens);
809        if let Some(generics) = &self.generics {
810            unsynn::ToTokens::to_tokens(generics, tokens);
811        }
812        unsynn::ToTokens::to_tokens(&self.target_type, tokens);
813        if let Some(for_trait) = &self.for_trait {
814            unsynn::ToTokens::to_tokens(for_trait, tokens);
815        }
816        if let Some(where_clause) = &self.where_clause {
817            unsynn::ToTokens::to_tokens(where_clause, tokens);
818        }
819        unsynn::ToTokens::to_tokens(&self.items, tokens);
820    }
821}
822
823impl quote::ToTokens for ModuleSig {
824    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
825        if let Some(attrs) = &self.attributes {
826            for attr in &attrs.0 {
827                unsynn::ToTokens::to_tokens(attr, tokens);
828            }
829        }
830        if let Some(vis) = &self.visibility {
831            quote::ToTokens::to_tokens(vis, tokens);
832        }
833        unsynn::ToTokens::to_tokens(&self._mod, tokens);
834        quote::ToTokens::to_tokens(&self.name, tokens);
835        unsynn::ToTokens::to_tokens(&self.items, tokens);
836    }
837}
838
839impl quote::ToTokens for TraitSig {
840    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
841        if let Some(attrs) = &self.attributes {
842            for attr in &attrs.0 {
843                unsynn::ToTokens::to_tokens(attr, tokens);
844            }
845        }
846        if let Some(vis) = &self.visibility {
847            quote::ToTokens::to_tokens(vis, tokens);
848        }
849        if let Some(unsafe_kw) = &self.unsafe_kw {
850            unsynn::ToTokens::to_tokens(unsafe_kw, tokens);
851        }
852        unsynn::ToTokens::to_tokens(&self._trait, tokens);
853        quote::ToTokens::to_tokens(&self.name, tokens);
854        if let Some(generics) = &self.generics {
855            unsynn::ToTokens::to_tokens(generics, tokens);
856        }
857        if let Some(bounds) = &self.bounds {
858            unsynn::ToTokens::to_tokens(bounds, tokens);
859        }
860        if let Some(where_clause) = &self.where_clause {
861            unsynn::ToTokens::to_tokens(where_clause, tokens);
862        }
863        unsynn::ToTokens::to_tokens(&self.items, tokens);
864    }
865}
866
867impl quote::ToTokens for ModuleContent {
868    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
869        // Output inner attributes first
870        if let Some(inner_attrs) = &self.inner_attrs {
871            for attr_delimited in &inner_attrs.0 {
872                quote::ToTokens::to_tokens(&attr_delimited.value, tokens);
873            }
874        }
875        unsynn::ToTokens::to_tokens(&self.items, tokens);
876    }
877}
878
879impl quote::ToTokens for EnumSig {
880    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
881        if let Some(attrs) = &self.attributes {
882            for attr in &attrs.0 {
883                unsynn::ToTokens::to_tokens(attr, tokens);
884            }
885        }
886        if let Some(vis) = &self.visibility {
887            quote::ToTokens::to_tokens(vis, tokens);
888        }
889        unsynn::ToTokens::to_tokens(&self._enum, tokens);
890        quote::ToTokens::to_tokens(&self.name, tokens);
891        if let Some(generics) = &self.generics {
892            unsynn::ToTokens::to_tokens(generics, tokens);
893        }
894        if let Some(where_clause) = &self.where_clause {
895            unsynn::ToTokens::to_tokens(where_clause, tokens);
896        }
897        unsynn::ToTokens::to_tokens(&self.variants, tokens);
898    }
899}
900
901impl quote::ToTokens for StructSig {
902    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
903        if let Some(attrs) = &self.attributes {
904            for attr in &attrs.0 {
905                unsynn::ToTokens::to_tokens(attr, tokens);
906            }
907        }
908        if let Some(vis) = &self.visibility {
909            quote::ToTokens::to_tokens(vis, tokens);
910        }
911        unsynn::ToTokens::to_tokens(&self._struct, tokens);
912        quote::ToTokens::to_tokens(&self.name, tokens);
913        if let Some(generics) = &self.generics {
914            unsynn::ToTokens::to_tokens(generics, tokens);
915        }
916        if let Some(where_clause) = &self.where_clause {
917            unsynn::ToTokens::to_tokens(where_clause, tokens);
918        }
919        quote::ToTokens::to_tokens(&self.body, tokens);
920    }
921}
922
923impl quote::ToTokens for StructBody {
924    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
925        match self {
926            StructBody::Named(fields) => unsynn::ToTokens::to_tokens(fields, tokens),
927            StructBody::Tuple(tuple) => unsynn::ToTokens::to_tokens(tuple, tokens),
928            StructBody::Unit(semi) => unsynn::ToTokens::to_tokens(semi, tokens),
929        }
930    }
931}
932
933impl quote::ToTokens for StructField {
934    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
935        if let Some(attrs) = &self.attributes {
936            for attr in &attrs.0 {
937                unsynn::ToTokens::to_tokens(attr, tokens);
938            }
939        }
940        if let Some(vis) = &self.visibility {
941            quote::ToTokens::to_tokens(vis, tokens);
942        }
943        quote::ToTokens::to_tokens(&self.name, tokens);
944        unsynn::ToTokens::to_tokens(&self._colon, tokens);
945        unsynn::ToTokens::to_tokens(&self.field_type, tokens);
946    }
947}
948
949impl quote::ToTokens for TypeAliasSig {
950    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
951        if let Some(attrs) = &self.attributes {
952            for attr in &attrs.0 {
953                unsynn::ToTokens::to_tokens(attr, tokens);
954            }
955        }
956        if let Some(vis) = &self.visibility {
957            quote::ToTokens::to_tokens(vis, tokens);
958        }
959        unsynn::ToTokens::to_tokens(&self._type, tokens);
960        quote::ToTokens::to_tokens(&self.name, tokens);
961        if let Some(generics) = &self.generics {
962            unsynn::ToTokens::to_tokens(generics, tokens);
963        }
964        unsynn::ToTokens::to_tokens(&self._eq, tokens);
965        unsynn::ToTokens::to_tokens(&self.target, tokens);
966        unsynn::ToTokens::to_tokens(&self._semi, tokens);
967    }
968}
969
970impl quote::ToTokens for ConstSig {
971    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
972        if let Some(attrs) = &self.attributes {
973            for attr in &attrs.0 {
974                unsynn::ToTokens::to_tokens(attr, tokens);
975            }
976        }
977        if let Some(vis) = &self.visibility {
978            quote::ToTokens::to_tokens(vis, tokens);
979        }
980        unsynn::ToTokens::to_tokens(&self._const, tokens);
981        quote::ToTokens::to_tokens(&self.name, tokens);
982        unsynn::ToTokens::to_tokens(&self._colon, tokens);
983        unsynn::ToTokens::to_tokens(&self.const_type, tokens);
984        unsynn::ToTokens::to_tokens(&self._eq, tokens);
985        unsynn::ToTokens::to_tokens(&self.value, tokens);
986        unsynn::ToTokens::to_tokens(&self._semi, tokens);
987    }
988}
989
990impl quote::ToTokens for StaticSig {
991    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
992        if let Some(attrs) = &self.attributes {
993            for attr in &attrs.0 {
994                unsynn::ToTokens::to_tokens(attr, tokens);
995            }
996        }
997        if let Some(vis) = &self.visibility {
998            quote::ToTokens::to_tokens(vis, tokens);
999        }
1000        if let Some(mut_kw) = &self.mut_kw {
1001            unsynn::ToTokens::to_tokens(mut_kw, tokens);
1002        }
1003        unsynn::ToTokens::to_tokens(&self._static, tokens);
1004        quote::ToTokens::to_tokens(&self.name, tokens);
1005        unsynn::ToTokens::to_tokens(&self._colon, tokens);
1006        unsynn::ToTokens::to_tokens(&self.static_type, tokens);
1007        unsynn::ToTokens::to_tokens(&self._eq, tokens);
1008        unsynn::ToTokens::to_tokens(&self.value, tokens);
1009        unsynn::ToTokens::to_tokens(&self._semi, tokens);
1010    }
1011}
1012
1013impl quote::ToTokens for EnumVariant {
1014    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1015        if let Some(attrs) = &self.attributes {
1016            for attr in &attrs.0 {
1017                unsynn::ToTokens::to_tokens(attr, tokens);
1018            }
1019        }
1020        quote::ToTokens::to_tokens(&self.name, tokens);
1021        if let Some(data) = &self.data {
1022            quote::ToTokens::to_tokens(data, tokens);
1023        }
1024    }
1025}
1026
1027impl quote::ToTokens for EnumVariantData {
1028    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
1029        match self {
1030            EnumVariantData::Tuple(paren) => unsynn::ToTokens::to_tokens(paren, tokens),
1031            EnumVariantData::Struct(brace) => unsynn::ToTokens::to_tokens(brace, tokens),
1032            EnumVariantData::Discriminant(disc) => unsynn::ToTokens::to_tokens(disc, tokens),
1033        }
1034    }
1035}
1036
1037#[cfg(test)]
1038mod tests;