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