diesel_derives/
diesel_for_each_tuple.rs1use proc_macro2::{Ident, Span, TokenStream};
2use quote::quote;
3
4pub(crate) fn expand(input: ForEachTupleInput) -> TokenStream {
5 let call_side = Span::mixed_site();
6
7 let pairs = (0..input.max_size as usize)
8 .map(|i| {
9 let (t, st, tt) = if i == 0 {
10 let t = Ident::new("T", call_side);
14 let st = Ident::new("ST", call_side);
15 let tt = Ident::new("TT", call_side);
16 (t, st, tt)
17 } else {
18 let t = Ident::new(&::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("T{0}", i)) })format!("T{i}"), call_side);
19 let st = Ident::new(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("ST{0}", i))
})format!("ST{i}"), call_side);
20 let tt = Ident::new(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("TT{0}", i))
})format!("TT{i}"), call_side);
21 (t, st, tt)
22 };
23 let i = syn::Index::from(i);
24 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&i, &mut _s);
_s
});
::quote::__private::push_rarrow(&mut _s);
::quote::ToTokens::to_tokens(&t, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&st, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&tt, &mut _s);
::quote::__private::push_comma(&mut _s);
_s
}quote!((#i) -> #t, #st, #tt,)
25 })
26 .collect::<Vec<_>>();
27
28 let mut out = Vec::with_capacity(input.max_size as usize);
29
30 for i in 0..input.max_size {
31 let items = &pairs[0..=i as usize];
32 let tuple = i + 1;
33 out.push({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&tuple, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut items, i) = items.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let items =
match items.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&items, &mut _s);
}
}
_s
});
_s
}quote! {
34 #tuple {
35 #(#items)*
36 }
37 });
38 }
39 let input = input.inner;
40
41 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&input, &mut _s);
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut out, i) = out.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let out =
match out.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&out, &mut _s);
}
}
_s
});
_s
}quote! {
42 #input! {
43 #(#out)*
44 }
45 }
46}
47
48pub struct ForEachTupleInput {
49 inner: Ident,
50 max_size: u16,
51}
52
53impl syn::parse::Parse for ForEachTupleInput {
54 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
55 let inner = input.parse()?;
56 input.parse::<::syn::token::Commasyn::Token![,]>()?;
57 let max_size = if input.peek(syn::Ident) {
58 let macro_ident = input.parse::<syn::Ident>()?;
59 if macro_ident != "env" {
60 return Err(syn::Error::new(
61 macro_ident.span(),
62 "only the `env!` macro is expected here",
63 ));
64 }
65 let _bang = input.parse::<::syn::token::Notsyn::Token![!]>()?;
66 let name;
67 match ::syn::__private::parse_parens(&input) {
::syn::__private::Ok(parens) => {
name = parens.content;
_ = name;
parens.token
}
::syn::__private::Err(error) => { return ::syn::__private::Err(error); }
};syn::parenthesized!(name in input);
68 let s = name.parse::<syn::LitStr>()?;
69 std::env::var(s.value())
70 .map_err(|_| {
71 syn::Error::new(
72 s.span(),
73 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Expected `{0}` to be set as environment variable",
s.value()))
})format!("Expected `{}` to be set as environment variable", s.value()),
74 )
75 })?
76 .parse::<u16>()
77 .map_err(|_| {
78 syn::Error::new(
79 s.span(),
80 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Expected `{0}` to be a u16 integer value",
s.value()))
})format!("Expected `{}` to be a u16 integer value", s.value()),
81 )
82 })?
83 } else {
84 input.parse::<syn::LitInt>()?.base10_parse()?
85 };
86 Ok(Self { inner, max_size })
87 }
88}