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::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