blob: e675baad25bbe0af61718252791f697be2c5873a [file] [log] [blame]
Austin Schuh6ea9bfa2023-08-06 19:05:10 -07001// Copyright 2023 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Newtype wrappers for `syn` types implementing a different
10//! `Debug` implementation that results in more concise output.
11
12use std::fmt::Display;
13
14use proc_macro2::TokenStream;
15use quote::ToTokens;
16use syn::punctuated::{Pair, Punctuated};
17
18macro_rules! minisyn_no_parse {
19 ($syntype:ident) => {
20 /// Equivalent to the identically-named `syn` type except
21 /// that its `Debug` implementation is more concise.
22 #[derive(Clone, Hash, Eq, PartialEq)]
23 pub struct $syntype(pub ::syn::$syntype);
24 impl std::fmt::Debug for $syntype {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
26 write!(f, "{}", self.0.to_token_stream().to_string())
27 }
28 }
29 impl ToTokens for $syntype
30 where
31 ::syn::$syntype: ToTokens,
32 {
33 fn to_tokens(&self, tokens: &mut TokenStream) {
34 self.0.to_tokens(tokens)
35 }
36
37 fn to_token_stream(&self) -> TokenStream {
38 self.0.to_token_stream()
39 }
40 fn into_token_stream(self) -> TokenStream
41 where
42 Self: Sized,
43 {
44 self.0.into_token_stream()
45 }
46 }
47 impl std::ops::Deref for $syntype {
48 type Target = ::syn::$syntype;
49 fn deref(&self) -> &Self::Target {
50 &self.0
51 }
52 }
53 impl std::ops::DerefMut for $syntype {
54 fn deref_mut(&mut self) -> &mut Self::Target {
55 &mut self.0
56 }
57 }
58 impl std::convert::From<::syn::$syntype> for $syntype {
59 fn from(inner: ::syn::$syntype) -> Self {
60 Self(inner)
61 }
62 }
63 impl std::convert::From<$syntype> for syn::$syntype {
64 fn from(inner: $syntype) -> Self {
65 inner.0
66 }
67 }
68 };
69}
70
71macro_rules! minisyn {
72 ($syntype:ident) => {
73 minisyn_no_parse!($syntype);
74
75 impl syn::parse::Parse for $syntype {
76 fn parse(input: syn::parse::ParseStream<'_>) -> syn::parse::Result<Self> {
77 syn::parse::Parse::parse(input).map(Self)
78 }
79 }
80 };
81}
82
83minisyn!(ItemMod);
84minisyn_no_parse!(Attribute);
85minisyn_no_parse!(AssocConst);
86minisyn_no_parse!(AssocType);
87minisyn!(Expr);
88minisyn!(ExprAssign);
89minisyn!(ExprAwait);
90minisyn!(ExprBinary);
91minisyn!(ExprBlock);
92minisyn!(ExprBreak);
93minisyn!(ExprConst);
94minisyn!(ExprCast);
95minisyn!(ExprField);
96minisyn_no_parse!(ExprGroup);
97minisyn!(ExprLet);
98minisyn!(ExprParen);
99minisyn!(ExprReference);
100minisyn!(ExprTry);
101minisyn!(ExprUnary);
102minisyn_no_parse!(Field);
103minisyn_no_parse!(Fields);
104minisyn!(ForeignItem);
105minisyn!(FnArg);
106minisyn!(GenericArgument);
107minisyn!(GenericParam);
108minisyn!(Ident);
109minisyn!(ImplItem);
110minisyn!(Item);
111minisyn!(ItemConst);
112minisyn!(ItemEnum);
113minisyn!(ItemForeignMod);
114minisyn!(ItemStruct);
115minisyn!(ItemType);
116minisyn!(ItemUse);
117minisyn!(LitBool);
118minisyn!(LitInt);
119minisyn!(Macro);
120minisyn_no_parse!(Pat);
121minisyn_no_parse!(PatType);
122minisyn_no_parse!(PatReference);
123minisyn_no_parse!(PatSlice);
124minisyn_no_parse!(PatTuple);
125minisyn!(Path);
126minisyn_no_parse!(PathArguments);
127minisyn!(PathSegment);
128minisyn!(Receiver);
129minisyn!(ReturnType);
130minisyn!(Signature);
131minisyn!(Stmt);
132minisyn!(TraitItem);
133minisyn!(Type);
134minisyn!(TypeArray);
135minisyn!(TypeGroup);
136minisyn!(TypeParamBound);
137minisyn!(TypeParen);
138minisyn!(TypePath);
139minisyn!(TypePtr);
140minisyn!(TypeReference);
141minisyn!(TypeSlice);
142minisyn!(Visibility);
143
144/// Converts a `syn::Punctuated` from being full of `syn` types to being
145/// full of `minisyn` types or vice-versa.
146pub(crate) fn minisynize_punctuated<T1, T2, S>(input: Punctuated<T1, S>) -> Punctuated<T2, S>
147where
148 T1: Into<T2>,
149{
150 input
151 .into_pairs()
152 .map(|p| match p {
153 Pair::Punctuated(t, p) => Pair::Punctuated(t.into(), p),
154 Pair::End(t) => Pair::End(t.into()),
155 })
156 .collect()
157}
158
159/// Converts a `Vec` from being full of `syn` types to being
160/// full of `minisyn` types or vice-versa.
161pub(crate) fn minisynize_vec<T1, T2>(input: Vec<T1>) -> Vec<T2>
162where
163 T1: Into<T2>,
164{
165 input.into_iter().map(Into::into).collect()
166}
167
168impl Ident {
169 pub(crate) fn new(string: &str, span: proc_macro2::Span) -> Self {
170 Self(syn::Ident::new(string, span))
171 }
172}
173
174impl Display for Ident {
175 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
176 f.write_str(&self.0.to_string())
177 }
178}
179
180impl<T> PartialEq<T> for Ident
181where
182 T: AsRef<str> + ?Sized,
183{
184 fn eq(&self, rhs: &T) -> bool {
185 self.0.eq(rhs)
186 }
187}