1 pub use diagnostic_shim::{Diagnostic, DiagnosticShim, EmitErrorExt};
2 
3 use meta::MetaItem;
4 use proc_macro2::{Span, TokenStream};
5 use syn::{Data, DeriveInput, GenericArgument, Ident, Type};
6 
wrap_in_dummy_mod(const_name: Ident, item: TokenStream) -> TokenStream7 pub fn wrap_in_dummy_mod(const_name: Ident, item: TokenStream) -> TokenStream {
8     quote! {
9         #[allow(non_snake_case, unused_extern_crates, unused_imports)]
10         fn #const_name() {
11             // https://github.com/rust-lang/rust/issues/47314
12             extern crate std;
13             use diesel;
14 
15             #item
16         }
17     }
18 }
19 
inner_of_option_ty(ty: &Type) -> &Type20 pub fn inner_of_option_ty(ty: &Type) -> &Type {
21     option_ty_arg(ty).unwrap_or(ty)
22 }
23 
is_option_ty(ty: &Type) -> bool24 pub fn is_option_ty(ty: &Type) -> bool {
25     option_ty_arg(ty).is_some()
26 }
27 
option_ty_arg(ty: &Type) -> Option<&Type>28 fn option_ty_arg(ty: &Type) -> Option<&Type> {
29     use syn::PathArguments::AngleBracketed;
30 
31     match *ty {
32         Type::Path(ref ty) => {
33             let last_segment = ty.path.segments.iter().last().unwrap();
34             match last_segment.arguments {
35                 AngleBracketed(ref args) if last_segment.ident == "Option" => {
36                     match args.args.iter().last() {
37                         Some(&GenericArgument::Type(ref ty)) => Some(ty),
38                         _ => None,
39                     }
40                 }
41                 _ => None,
42             }
43         }
44         _ => None,
45     }
46 }
47 
ty_for_foreign_derive(item: &DeriveInput, flags: &MetaItem) -> Result<Type, Diagnostic>48 pub fn ty_for_foreign_derive(item: &DeriveInput, flags: &MetaItem) -> Result<Type, Diagnostic> {
49     if flags.has_flag("foreign_derive") {
50         match item.data {
51             Data::Struct(ref body) => match body.fields.iter().nth(0) {
52                 Some(field) => Ok(field.ty.clone()),
53                 None => Err(flags
54                     .span()
55                     .error("foreign_derive requires at least one field")),
56             },
57             _ => Err(flags
58                 .span()
59                 .error("foreign_derive can only be used with structs")),
60         }
61     } else {
62         let ident = &item.ident;
63         let (_, ty_generics, ..) = item.generics.split_for_impl();
64         Ok(parse_quote!(#ident #ty_generics))
65     }
66 }
67 
fix_span(maybe_bad_span: Span, mut fallback: Span) -> Span68 pub fn fix_span(maybe_bad_span: Span, mut fallback: Span) -> Span {
69     let bad_span_debug = "#0 bytes(0..0)";
70 
71     if format!("{:?}", fallback) == bad_span_debug {
72         // On recent rust nightlies, even our fallback span is bad.
73         fallback = Span::call_site();
74     }
75 
76     if format!("{:?}", maybe_bad_span) == bad_span_debug {
77         fallback
78     } else {
79         maybe_bad_span
80     }
81 }
82