ferment_sys/ast/
mod.rs

1mod opposed;
2mod path_holder;
3mod type_holder;
4mod typepath_holder;
5mod wrapped;
6
7use std::hash::Hash;
8use quote::ToTokens;
9use syn::__private::TokenStream2;
10use syn::punctuated::Punctuated;
11use syn::token::{Brace, Comma, Dot, FatArrow, Paren, PathSep, Plus, Semi};
12pub use opposed::*;
13pub use path_holder::*;
14pub use type_holder::*;
15pub use typepath_holder::*;
16pub use wrapped::*;
17
18#[allow(unused)]
19pub type CommaPunctuated<T> = Punctuated<T, Comma>;
20#[allow(unused)]
21pub type CommaPunctuatedTokens = CommaPunctuated<TokenStream2>;
22#[allow(unused)]
23pub type Depunctuated<T> = Punctuated<T, Void>;
24#[allow(unused)]
25pub type BraceWrapped<S, SP> = Wrapped<S, SP, Brace>;
26#[allow(unused)]
27pub type ParenWrapped<S, SP> = Wrapped<S, SP, Paren>;
28#[allow(unused)]
29pub type CommaParenWrapped<S> = Wrapped<S, Comma, Paren>;
30#[allow(unused)]
31pub type SemiPunctuated<T> = Punctuated<T, Semi>;
32#[allow(unused)]
33pub type SemiPunctuatedTokens = SemiPunctuated<TokenStream2>;
34#[allow(unused)]
35pub type Colon2Punctuated<T> = Punctuated<T, PathSep>;
36#[allow(unused)]
37pub type AddPunctuated<T> = Punctuated<T, Plus>;
38#[allow(unused)]
39pub type DotPunctuated<T> = Punctuated<T, Dot>;
40
41#[allow(unused)]
42pub type Assignment<T1, T2> = Opposed<T1, T2, syn::token::Eq>;
43#[allow(unused)]
44pub type Lambda<T1, T2> = Opposed<T1, T2, FatArrow>;
45
46pub trait Holder: Clone + PartialEq + Eq + Hash + std::fmt::Debug + std::fmt::Display {
47    type Inner: ToTokens;
48    fn inner(&self) -> &Self::Inner;
49}
50
51
52#[macro_export]
53macro_rules! impl_holder {
54    ($holder_name:ident, $inner_type:ty) => {
55        #[derive(Clone)]
56        pub struct $holder_name(pub $inner_type);
57
58        impl Holder for $holder_name {
59            type Inner = $inner_type;
60
61            fn inner(&self) -> &Self::Inner {
62                &self.0
63            }
64        }
65
66        impl PartialEq for $holder_name {
67            fn eq(&self, other: &Self) -> bool {
68                self.inner().to_token_stream().to_string() == other.inner().to_token_stream().to_string()
69            }
70        }
71
72        impl Eq for $holder_name {}
73
74        impl std::hash::Hash for $holder_name {
75            fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
76                self.inner().to_token_stream().to_string().hash(state);
77            }
78        }
79
80        impl std::fmt::Debug for $holder_name {
81            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82                f.write_str(crate::formatter::format_token_stream(self.inner()).as_str())
83            }
84        }
85
86        impl std::fmt::Display for $holder_name {
87            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88                std::fmt::Debug::fmt(self, f)
89            }
90        }
91
92        impl<'a> From<&'a $inner_type> for $holder_name {
93            fn from(value: &'a $inner_type) -> Self {
94                Self(value.clone())
95            }
96        }
97        impl From<$inner_type> for $holder_name {
98            fn from(value: $inner_type) -> Self {
99                Self(value)
100            }
101        }
102        // impl syn::ParseQuote for $holder_name {
103        //     fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
104        //         <$inner_type>::parse(input)
105        //             .map($holder_name::from)
106        //     }
107        // }
108
109        impl syn::parse::Parse for $holder_name {
110            fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
111                <$inner_type as syn::parse::Parse>::parse(input).map($holder_name)
112            }
113        }
114
115
116
117        impl quote::ToTokens for $holder_name {
118            fn to_tokens(&self, tokens: &mut syn::__private::TokenStream2) {
119                self.inner().to_tokens(tokens)
120            }
121        }
122
123    };
124}
125//impl_holder!(GenericsHolder, Generics);