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