1 use crate::algorithm::Printer; 2 use crate::iter::IterDelimited; 3 use crate::path::PathKind; 4 use crate::INDENT; 5 use proc_macro2::TokenStream; 6 use syn::{ 7 Abi, BareFnArg, BareVariadic, ReturnType, Type, TypeArray, TypeBareFn, TypeGroup, 8 TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, TypeReference, 9 TypeSlice, TypeTraitObject, TypeTuple, 10 }; 11 12 impl Printer { ty(&mut self, ty: &Type)13 pub fn ty(&mut self, ty: &Type) { 14 match ty { 15 Type::Array(ty) => self.type_array(ty), 16 Type::BareFn(ty) => self.type_bare_fn(ty), 17 Type::Group(ty) => self.type_group(ty), 18 Type::ImplTrait(ty) => self.type_impl_trait(ty), 19 Type::Infer(ty) => self.type_infer(ty), 20 Type::Macro(ty) => self.type_macro(ty), 21 Type::Never(ty) => self.type_never(ty), 22 Type::Paren(ty) => self.type_paren(ty), 23 Type::Path(ty) => self.type_path(ty), 24 Type::Ptr(ty) => self.type_ptr(ty), 25 Type::Reference(ty) => self.type_reference(ty), 26 Type::Slice(ty) => self.type_slice(ty), 27 Type::TraitObject(ty) => self.type_trait_object(ty), 28 Type::Tuple(ty) => self.type_tuple(ty), 29 Type::Verbatim(ty) => self.type_verbatim(ty), 30 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] 31 _ => unimplemented!("unknown Type"), 32 } 33 } 34 type_array(&mut self, ty: &TypeArray)35 fn type_array(&mut self, ty: &TypeArray) { 36 self.word("["); 37 self.ty(&ty.elem); 38 self.word("; "); 39 self.expr(&ty.len); 40 self.word("]"); 41 } 42 type_bare_fn(&mut self, ty: &TypeBareFn)43 fn type_bare_fn(&mut self, ty: &TypeBareFn) { 44 if let Some(bound_lifetimes) = &ty.lifetimes { 45 self.bound_lifetimes(bound_lifetimes); 46 } 47 if ty.unsafety.is_some() { 48 self.word("unsafe "); 49 } 50 if let Some(abi) = &ty.abi { 51 self.abi(abi); 52 } 53 self.word("fn("); 54 self.cbox(INDENT); 55 self.zerobreak(); 56 for bare_fn_arg in ty.inputs.iter().delimited() { 57 self.bare_fn_arg(&bare_fn_arg); 58 self.trailing_comma(bare_fn_arg.is_last && ty.variadic.is_none()); 59 } 60 if let Some(variadic) = &ty.variadic { 61 self.bare_variadic(variadic); 62 self.zerobreak(); 63 } 64 self.offset(-INDENT); 65 self.end(); 66 self.word(")"); 67 self.return_type(&ty.output); 68 } 69 type_group(&mut self, ty: &TypeGroup)70 fn type_group(&mut self, ty: &TypeGroup) { 71 self.ty(&ty.elem); 72 } 73 type_impl_trait(&mut self, ty: &TypeImplTrait)74 fn type_impl_trait(&mut self, ty: &TypeImplTrait) { 75 self.word("impl "); 76 for type_param_bound in ty.bounds.iter().delimited() { 77 if !type_param_bound.is_first { 78 self.word(" + "); 79 } 80 self.type_param_bound(&type_param_bound); 81 } 82 } 83 type_infer(&mut self, ty: &TypeInfer)84 fn type_infer(&mut self, ty: &TypeInfer) { 85 let _ = ty; 86 self.word("_"); 87 } 88 type_macro(&mut self, ty: &TypeMacro)89 fn type_macro(&mut self, ty: &TypeMacro) { 90 let semicolon = false; 91 self.mac(&ty.mac, None, semicolon); 92 } 93 type_never(&mut self, ty: &TypeNever)94 fn type_never(&mut self, ty: &TypeNever) { 95 let _ = ty; 96 self.word("!"); 97 } 98 type_paren(&mut self, ty: &TypeParen)99 fn type_paren(&mut self, ty: &TypeParen) { 100 self.word("("); 101 self.ty(&ty.elem); 102 self.word(")"); 103 } 104 type_path(&mut self, ty: &TypePath)105 fn type_path(&mut self, ty: &TypePath) { 106 self.qpath(&ty.qself, &ty.path, PathKind::Type); 107 } 108 type_ptr(&mut self, ty: &TypePtr)109 fn type_ptr(&mut self, ty: &TypePtr) { 110 self.word("*"); 111 if ty.mutability.is_some() { 112 self.word("mut "); 113 } else { 114 self.word("const "); 115 } 116 self.ty(&ty.elem); 117 } 118 type_reference(&mut self, ty: &TypeReference)119 fn type_reference(&mut self, ty: &TypeReference) { 120 self.word("&"); 121 if let Some(lifetime) = &ty.lifetime { 122 self.lifetime(lifetime); 123 self.nbsp(); 124 } 125 if ty.mutability.is_some() { 126 self.word("mut "); 127 } 128 self.ty(&ty.elem); 129 } 130 type_slice(&mut self, ty: &TypeSlice)131 fn type_slice(&mut self, ty: &TypeSlice) { 132 self.word("["); 133 self.ty(&ty.elem); 134 self.word("]"); 135 } 136 type_trait_object(&mut self, ty: &TypeTraitObject)137 fn type_trait_object(&mut self, ty: &TypeTraitObject) { 138 self.word("dyn "); 139 for type_param_bound in ty.bounds.iter().delimited() { 140 if !type_param_bound.is_first { 141 self.word(" + "); 142 } 143 self.type_param_bound(&type_param_bound); 144 } 145 } 146 type_tuple(&mut self, ty: &TypeTuple)147 fn type_tuple(&mut self, ty: &TypeTuple) { 148 self.word("("); 149 self.cbox(INDENT); 150 self.zerobreak(); 151 for elem in ty.elems.iter().delimited() { 152 self.ty(&elem); 153 if ty.elems.len() == 1 { 154 self.word(","); 155 self.zerobreak(); 156 } else { 157 self.trailing_comma(elem.is_last); 158 } 159 } 160 self.offset(-INDENT); 161 self.end(); 162 self.word(")"); 163 } 164 165 #[cfg(not(feature = "verbatim"))] type_verbatim(&mut self, ty: &TokenStream)166 fn type_verbatim(&mut self, ty: &TokenStream) { 167 unimplemented!("Type::Verbatim `{}`", ty); 168 } 169 170 #[cfg(feature = "verbatim")] type_verbatim(&mut self, tokens: &TokenStream)171 fn type_verbatim(&mut self, tokens: &TokenStream) { 172 use syn::parse::{Parse, ParseStream, Result}; 173 use syn::punctuated::Punctuated; 174 use syn::{Token, TypeParamBound}; 175 176 enum TypeVerbatim { 177 DynStar(DynStar), 178 MutSelf(MutSelf), 179 NotType(NotType), 180 } 181 182 struct DynStar { 183 bounds: Punctuated<TypeParamBound, Token![+]>, 184 } 185 186 struct MutSelf { 187 ty: Option<Type>, 188 } 189 190 struct NotType { 191 inner: Type, 192 } 193 194 impl Parse for TypeVerbatim { 195 fn parse(input: ParseStream) -> Result<Self> { 196 let lookahead = input.lookahead1(); 197 if lookahead.peek(Token![dyn]) { 198 input.parse::<Token![dyn]>()?; 199 input.parse::<Token![*]>()?; 200 let bounds = input.parse_terminated(TypeParamBound::parse, Token![+])?; 201 Ok(TypeVerbatim::DynStar(DynStar { bounds })) 202 } else if lookahead.peek(Token![mut]) { 203 input.parse::<Token![mut]>()?; 204 input.parse::<Token![self]>()?; 205 let ty = if input.is_empty() { 206 None 207 } else { 208 input.parse::<Token![:]>()?; 209 let ty: Type = input.parse()?; 210 Some(ty) 211 }; 212 Ok(TypeVerbatim::MutSelf(MutSelf { ty })) 213 } else if lookahead.peek(Token![!]) { 214 input.parse::<Token![!]>()?; 215 let inner: Type = input.parse()?; 216 Ok(TypeVerbatim::NotType(NotType { inner })) 217 } else { 218 Err(lookahead.error()) 219 } 220 } 221 } 222 223 let ty: TypeVerbatim = match syn::parse2(tokens.clone()) { 224 Ok(ty) => ty, 225 Err(_) => unimplemented!("Type::Verbatim `{}`", tokens), 226 }; 227 228 match ty { 229 TypeVerbatim::DynStar(ty) => { 230 self.word("dyn* "); 231 for type_param_bound in ty.bounds.iter().delimited() { 232 if !type_param_bound.is_first { 233 self.word(" + "); 234 } 235 self.type_param_bound(&type_param_bound); 236 } 237 } 238 TypeVerbatim::MutSelf(bare_fn_arg) => { 239 self.word("mut self"); 240 if let Some(ty) = &bare_fn_arg.ty { 241 self.word(": "); 242 self.ty(ty); 243 } 244 } 245 TypeVerbatim::NotType(ty) => { 246 self.word("!"); 247 self.ty(&ty.inner); 248 } 249 } 250 } 251 return_type(&mut self, ty: &ReturnType)252 pub fn return_type(&mut self, ty: &ReturnType) { 253 match ty { 254 ReturnType::Default => {} 255 ReturnType::Type(_arrow, ty) => { 256 self.word(" -> "); 257 self.ty(ty); 258 } 259 } 260 } 261 bare_fn_arg(&mut self, bare_fn_arg: &BareFnArg)262 fn bare_fn_arg(&mut self, bare_fn_arg: &BareFnArg) { 263 self.outer_attrs(&bare_fn_arg.attrs); 264 if let Some((name, _colon)) = &bare_fn_arg.name { 265 self.ident(name); 266 self.word(": "); 267 } 268 self.ty(&bare_fn_arg.ty); 269 } 270 bare_variadic(&mut self, variadic: &BareVariadic)271 fn bare_variadic(&mut self, variadic: &BareVariadic) { 272 self.outer_attrs(&variadic.attrs); 273 if let Some((name, _colon)) = &variadic.name { 274 self.ident(name); 275 self.word(": "); 276 } 277 self.word("..."); 278 } 279 abi(&mut self, abi: &Abi)280 pub fn abi(&mut self, abi: &Abi) { 281 self.word("extern "); 282 if let Some(name) = &abi.name { 283 self.lit_str(name); 284 self.nbsp(); 285 } 286 } 287 } 288