// Copyright 2018 The proptest developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! High level IR and abstract syntax tree (AST) of impls.
//!
//! We compile to this AST and then linearise that to Rust code.

use std::ops::{Add, AddAssign};

use syn;
use syn::spanned::Spanned;
use proc_macro2::{TokenStream, Span};
use quote::{ToTokens, TokenStreamExt};

use crate::util::self_ty;
use crate::use_tracking::UseTracker;
use crate::error::{Ctx, DeriveResult};

//==============================================================================
// Config
//==============================================================================

/// The `MAX - 1` number of strategies that `TupleUnion` supports.
/// Increase this if the behaviour is changed in `proptest`.
/// Keeping this lower than what `proptest` supports will also work
/// but for optimality this should follow what `proptest` supports.
const UNION_CHUNK_SIZE: usize = 9;

/// The name of the top parameter variable name given in `arbitrary_with`.
/// Changing this is not a breaking change because a user is expected not
/// to rely on this (and the user shouldn't be able to..).
const TOP_PARAM_NAME: &str = "_top";

/// The name of the variable name used for user facing parameter types
/// specified in a `#[proptest(params = "<type>")]` attribute.
///
/// Changing the value of this constant constitutes a breaking change!
const API_PARAM_NAME: &str = "params";

//==============================================================================
// AST Root
//==============================================================================

/// Top level AST and everything required to implement `Arbitrary` for any
/// given type. Linearizing this AST gives you the impl wrt. Rust code.
pub struct Impl {
    /// Name of the type.
    typ: syn::Ident,
    /// Tracker for uses of Arbitrary trait for a generic type.
    tracker: UseTracker,
    /// The three main parts, see description of `ImplParts` for details.
    parts: ImplParts,
}

/// The three main parts to deriving `Arbitrary` for a type.
/// That is: the associated items `Parameters` (`Params`),
/// `Strategy` (`Strategy`) as well as the construction of the
/// strategy itself (`Ctor`).
pub type ImplParts = (Params, Strategy, Ctor);

impl Impl {
    /// Constructs a new `Impl` from the parts as described on the type.
    pub fn new(typ: syn::Ident, tracker: UseTracker, parts: ImplParts) -> Self {
        Self { typ, tracker, parts }
    }

    /// Linearises the impl into a sequence of tokens.
    /// This produces the actual Rust code for the impl.
    pub fn into_tokens(self, ctx: Ctx) -> DeriveResult<TokenStream> {
        let Impl { typ, mut tracker, parts: (params, strategy, ctor) } = self;

        /// A `Debug` bound on a type variable.
        fn debug_bound() -> syn::TypeParamBound {
            parse_quote!( ::std::fmt::Debug )
        }

        /// An `Arbitrary` bound on a type variable.
        fn arbitrary_bound() -> syn::TypeParamBound {
            parse_quote!( _proptest::arbitrary::Arbitrary )
        }

        // Add bounds and get generics for the impl.
        tracker.add_bounds(ctx, &arbitrary_bound(), Some(debug_bound()))?;
        let generics = tracker.consume();
        let (impl_generics, ty_generics, where_clause)
          = generics.split_for_impl();

        let _top = call_site_ident(TOP_PARAM_NAME);

        let _const = call_site_ident(
            &format!("_IMPL_ARBITRARY_FOR_{}", typ));

        // Linearise everything. We're done after this.
        let q = quote! {
            #[allow(non_upper_case_globals)]
            const #_const: () = {
            extern crate proptest as _proptest;

            impl #impl_generics _proptest::arbitrary::Arbitrary
            for #typ #ty_generics #where_clause {
                type Parameters = #params;

                type Strategy = #strategy;

                fn arbitrary_with(#_top: Self::Parameters) -> Self::Strategy {
                    #ctor
                }
            }

            };
        };

        Ok(q)
    }
}

//==============================================================================
// Smart construcors, StratPair
//==============================================================================

/// A pair of `Strategy` and `Ctor`. These always come in pairs.
pub type StratPair = (Strategy, Ctor);

/// The type and constructor for `any::<Type>()`.
pub fn pair_any(ty: syn::Type, span: Span) -> StratPair {
    let q = Ctor::Arbitrary(ty.clone(), None, span);
    (Strategy::Arbitrary(ty, span), q)
}

/// The type and constructor for `any_with::<Type>(parameters)`.
pub fn pair_any_with(ty: syn::Type, var: usize, span: Span) -> StratPair {
    let q = Ctor::Arbitrary(ty.clone(), Some(var), span);
    (Strategy::Arbitrary(ty, span), q)
}

/// The type and constructor for a specific strategy value constructed by the
/// given expression. Currently, the type is erased and a `BoxedStrategy<Type>`
/// is given back instead.
///
/// This is a temporary restriction. Once `impl Trait` is stabilized,
/// the boxing and dynamic dispatch can be replaced with a statically
/// dispatched anonymous type instead.
pub fn pair_existential(ty: syn::Type, strat: syn::Expr) -> StratPair {
    (Strategy::Existential(ty), Ctor::Existential(strat))
}

/// The type and constructor for a strategy that always returns the value
/// provided in the expression `val`.
/// This is statically dispatched since no erasure is needed or used.
pub fn pair_value(ty: syn::Type, val: syn::Expr) -> StratPair {
    (Strategy::Value(ty), Ctor::Value(val))
}

/// Same as `pair_existential` for the `Self` type.
pub fn pair_existential_self(strat: syn::Expr) -> StratPair {
    pair_existential(self_ty(), strat)
}

/// Same as `pair_value` for the `Self` type.
pub fn pair_value_self(val: syn::Expr) -> StratPair {
    pair_value(self_ty(), val)
}

/// Erased strategy for a fixed value.
pub fn pair_value_exist(ty: syn::Type, strat: syn::Expr) -> StratPair {
    (Strategy::Existential(ty), Ctor::ValueExistential(strat))
}

/// Erased strategy for a fixed value.
pub fn pair_value_exist_self(strat: syn::Expr) -> StratPair {
    pair_value_exist(self_ty(), strat)
}

/// Same as `pair_value` but for a unit variant or unit struct.
pub fn pair_unit_self(path: &syn::Path) -> StratPair {
    pair_value_self(parse_quote!( #path {} ))
}

/// The type and constructor for `#[proptest(regex(..))]`.
pub fn pair_regex(ty: syn::Type, regex: syn::Expr) -> StratPair {
    (Strategy::Regex(ty.clone()), Ctor::Regex(ty, regex))
}

/// Same as `pair_regex` for the `Self` type.
pub fn pair_regex_self(regex: syn::Expr) -> StratPair {
    pair_regex(self_ty(), regex)
}

/// The type and constructor for .prop_map:ing a set of strategies
/// into the type we are implementing for. The closure for the
/// `.prop_map(<closure>)` must also be given.
pub fn pair_map((strats, ctors): (Vec<Strategy>, Vec<Ctor>), closure: MapClosure)
    -> StratPair
{
    (Strategy::Map(strats.into()), Ctor::Map(ctors.into(), closure))
}

/// The type and constructor for a union of strategies which produces a new
/// strategy that used the given strategies with probabilities based on the
/// assigned relative weights for each strategy.
pub fn pair_oneof((strats, ctors): (Vec<Strategy>, Vec<(u32, Ctor)>))
    -> StratPair
{
    (Strategy::Union(strats.into()), Ctor::Union(ctors.into()))
}

/// Potentially apply a filter to a strategy type and its constructor.
pub fn pair_filter(filter: Vec<syn::Expr>, ty: syn::Type, pair: StratPair)
    -> StratPair
{
    filter.into_iter().fold(pair, |(strat, ctor), filter| (
        Strategy::Filter(Box::new(strat), ty.clone()),
        Ctor::Filter(Box::new(ctor), filter)
    ))
}

//==============================================================================
// Parameters
//==============================================================================

/// Represents the associated item of `Parameters` of an `Arbitrary` impl.
pub struct Params(Vec<syn::Type>);

impl Params {
    /// Construct an `empty` list of parameters.
    /// This is equivalent to the unit type `()`.
    pub fn empty() -> Self {
        Params(Vec::new())
    }

    /// Computes and returns the number of parameter types.
    pub fn len(&self) -> usize {
        self.0.len()
    }
}

impl From<Params> for syn::Type {
    fn from(x: Params) -> Self {
        let tys = x.0;
        parse_quote!( (#(#tys),*) )
    }
}

impl Add<syn::Type> for Params {
    type Output = Params;

    fn add(mut self, rhs: syn::Type) -> Self::Output {
        self.0.push(rhs);
        self
    }
}

impl AddAssign<syn::Type> for Params {
    fn add_assign(&mut self, rhs: syn::Type) {
        self.0.push(rhs);
    }
}

impl ToTokens for Params {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        Tuple2(self.0.as_slice()).to_tokens(tokens)
    }
}

/// Returns for a given type `ty` the associated item `Parameters` of the
/// type's `Arbitrary` implementation.
pub fn arbitrary_param(ty: &syn::Type) -> syn::Type {
    parse_quote!(<#ty as _proptest::arbitrary::Arbitrary>::Parameters)
}

//==============================================================================
// Strategy
//==============================================================================

/// The type of a given `Strategy`.
pub enum Strategy {
    /// Assuming the metavariable `$ty` for a given type, this models the
    /// strategy type `<$ty as Arbitrary>::Strategy`.
    Arbitrary(syn::Type, Span),
    /// This models <$ty as StrategyFromRegex>::Strategy.
    Regex(syn::Type),
    /// Assuming the metavariable `$ty` for a given type, this models the
    /// strategy type `BoxedStrategy<$ty>`, i.e: an existentially typed strategy.
    ///
    /// The dynamic dispatch used here is an implementation detail that may be
    /// changed. Such a change does not count as a breakage semver wise.
    Existential(syn::Type),
    /// Assuming the metavariable `$ty` for a given type, this models a
    /// non-shrinking strategy that simply always returns a value of the
    /// given type.
    Value(syn::Type),
    /// Assuming a sequence of strategies, this models a mapping from that
    /// sequence to `Self`.
    Map(Box<[Strategy]>),
    /// Assuming a sequence of relative-weighted strategies, this models a
    /// weighted choice of those strategies. The resultant strategy will in
    /// other words randomly pick one strategy with probabilities based on the
    /// specified weights.
    Union(Box<[Strategy]>),
    /// A filtered strategy with `.prop_filter`.
    Filter(Box<Strategy>, syn::Type),
}

macro_rules! quote_append {
    ($tokens: expr, $($quasi: tt)*) => {
        $tokens.append_all(quote!($($quasi)*))
    };
}

impl Strategy {
    fn types(&self) -> Vec<syn::Type> {
        use self::Strategy::*;
        match self {
            Arbitrary(ty, _) => vec![ty.clone()],
            Regex(ty) => vec![ty.clone()],
            Existential(ty) => vec![ty.clone()],
            Value(ty) => vec![ty.clone()],
            Map(strats) => strats.iter().flat_map(|s| s.types()).collect(),
            Union(strats) => strats.iter().flat_map(|s| s.types()).collect(),
            Filter(_, ty) => vec![ty.clone()],
        }
    }
}

impl ToTokens for Strategy {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        // The logic of each of these are pretty straight forward save for
        // union which is described separately.
        use self::Strategy::*;
        match self {
            Arbitrary(ty, span) => tokens.append_all(quote_spanned!(*span=>
                <#ty as _proptest::arbitrary::Arbitrary>::Strategy
            )),
            Regex(ty) => quote_append!(tokens,
                <#ty as _proptest::string::StrategyFromRegex>::Strategy
            ),
            Existential(ty) => quote_append!(tokens,
                _proptest::strategy::BoxedStrategy<#ty>
            ),
            Value(ty) => quote_append!(tokens, fn() -> #ty ),
            Map(strats) => {
                let field_tys = self.types();
                let strats = strats.iter();
                quote_append!(tokens,
                    _proptest::strategy::Map< ( #(#strats,)* ),
                        fn( ( #(#field_tys,)* ) ) -> Self
                    >
                )
            },
            Union(strats) => union_strat_to_tokens(tokens, strats),
            Filter(strat, ty) => {
                quote_append!(tokens,
                    _proptest::strategy::Filter<#strat, fn(&#ty) -> bool>
                )
            },
        }
    }
}

//==============================================================================
// Constructor
//==============================================================================

/// The right hand side (RHS) of a let binding of parameters.
pub enum FromReg {
    /// Denotes a move from the top parameter given in the arguments of
    /// `arbitrary_with`.
    Top,
    /// Denotes a move from a variable `params_<x>` where `<x>` is the given
    /// number.
    Num(usize),
}

/// The left hand side (LHS) of a let binding of parameters.
pub enum ToReg {
    /// Denotes a move and declaration to a sequence of variables from
    /// `params_0` to `params_x`.
    Range(usize),
    /// Denotes a move and declaration of a special variable `params` that is
    /// user facing and is ALWAYS named `params`.
    ///
    /// To change the name this linearises to is considered a breaking change
    /// wrt. semver.
    API,
}

/// Models an expression that generates a proptest `Strategy`.
pub enum Ctor {
    /// A strategy generated by using the `Arbitrary` impl for the given `Ty´.
    /// If `Some(idx)` is specified, then a parameter at `params_<idx>` is used
    /// and provided to `any_with::<Ty>(params_<idx>)`.
    Arbitrary(syn::Type, Option<usize>, Span),
    /// A strategy that is generated by a mapping a regex in the form of a
    /// string slice to the actual regex.
    Regex(syn::Type, syn::Expr),
    /// An exact strategy value given by the expression.
    Existential(syn::Expr),
    /// A strategy that always produces the given expression.
    Value(syn::Expr),
    /// A strategy that always produces the given expression but which is erased.
    ValueExistential(syn::Expr),
    /// A strategy that maps from a sequence of strategies into `Self`.
    Map(Box<[Ctor]>, MapClosure),
    /// A strategy that randomly selects one of the given relative-weighted
    /// strategies.
    Union(Box<[(u32, Ctor)]>),
    /// A let binding that moves to and declares the `ToReg` from the `FromReg`
    /// as well as the strategy that uses the `ToReg`.
    Extract(Box<Ctor>, ToReg, FromReg),
    /// A filtered strategy with `.prop_filter`.
    Filter(Box<Ctor>, syn::Expr),
}

/// Wraps the given strategy producing expression with a move into
/// `params_<to>` from `FromReg`. This is used when the given `c` expects
/// `params_<to>` to be there.
pub fn extract_all(c: Ctor, to: usize, from: FromReg) -> Ctor {
    extract(c, ToReg::Range(to), from)
}

/// Wraps the given strategy producing expression with a move into `params`
/// (literally named like that) from `FromReg`. This is used when the given
/// `c` expects `params` to be there.
pub fn extract_api(c: Ctor, from: FromReg) -> Ctor {
    extract(c, ToReg::API, from)
}

impl ToTokens for FromReg {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        match self {
            FromReg::Top => call_site_ident(TOP_PARAM_NAME).to_tokens(tokens),
            FromReg::Num(reg) => param(*reg).to_tokens(tokens),
        }
    }
}

impl ToTokens for ToReg {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        match *self {
            ToReg::Range(to) if to == 1 => param(0).to_tokens(tokens),
            ToReg::Range(to) => Tuple((0..to).map(param)).to_tokens(tokens),
            ToReg::API => call_site_ident(API_PARAM_NAME).to_tokens(tokens),
        }
    }
}

impl ToTokens for Ctor {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        // The logic of each of these are pretty straight forward save for
        // union which is described separately.
        use self::Ctor::*;
        match self {
            Filter(ctor, filter) => quote_append!(tokens,
                _proptest::strategy::Strategy::prop_filter(
                    #ctor, stringify!(#filter), #filter)
            ),
            Extract(ctor, to, from) => quote_append!(tokens, {
                let #to = #from; #ctor
            }),
            Arbitrary(ty, fv, span) => tokens.append_all(if let Some(fv) = fv {
                let args = param(*fv);
                quote_spanned!(*span=>
                    _proptest::arbitrary::any_with::<#ty>(#args)
                )
            } else {
                quote_spanned!(*span=>
                    _proptest::arbitrary::any::<#ty>()
                )
            }),
            Regex(ty, regex) => quote_append!(tokens,
                <#ty as _proptest::string::StrategyFromRegex>::from_regex(#regex)
            ),
            Existential(expr) => quote_append!(tokens,
                _proptest::strategy::Strategy::boxed( #expr ) ),
            Value(expr) => quote_append!(tokens, || #expr ),
            ValueExistential(expr) => quote_append!(tokens,
                _proptest::strategy::Strategy::boxed(
                    _proptest::strategy::LazyJust::new(move || #expr)
                )
            ),
            Map(ctors, closure) => {
                let ctors = ctors.iter();
                quote_append!(tokens,
                    _proptest::strategy::Strategy::prop_map(
                        ( #(#ctors,)* ),
                        #closure
                    )
                );
            },
            Union(ctors) => union_ctor_to_tokens(tokens, ctors),
        }
    }
}

/// Tokenizes a weighted list of `Ctor`.
///
/// The logic is that the output should be as linear as possible while still
/// supporting enums with an unbounded number of variants without any boxing
/// (erasure) or dynamic dispatch.
///
/// As `TupleUnion` is (currently) limited to 10 summands in the coproduct we
/// can't just emit the entire thing linearly as this will fail on the 11:th
/// variant.
///
/// A naive approach to solve might be to simply use a cons-list like so:
///
/// ```ignore
/// TupleUnion::new(
///     (w_1, s_1),
///     (w_2 + w_3 + w_4 + w_5,
///      TupleUnion::new(
///         (w_2, s_2),
///         (w_3 + w_4 + w_5,
///          TupleUnion::new(
///             (w_3, s_3),
///             (w_4 + w_5,
///              TupleUnion::new(
///                 (w_4, s_4),
///                 (w_5, s_5),
///             ))
///         ))
///     ))
/// )
/// ```
///
/// However, we can do better by being linear for the `10 - 1` first
/// strategies and then switch to nesting like so:
///
/// ```ignore
/// (1, 2, 3, 4, 5, 6, 7, 8, 9,
///     (10, 11, 12, 13, 14, 15, 16, 17, 18,
///         (19, ..)))
/// ```
fn union_ctor_to_tokens(tokens: &mut TokenStream, ctors: &[(u32, Ctor)]) {
    if ctors.is_empty() { return; }

    if let [(_, ctor)] = ctors {
        // This is not a union at all - user provided an enum with one variant.
        ctor.to_tokens(tokens);
        return;
    }

    let mut chunks = ctors.chunks(UNION_CHUNK_SIZE);
    let chunk = chunks.next().unwrap();
    let head = chunk.iter().map(|(w, c)| quote!( (#w, #c) ));
    let tail = Recurse(weight_sum(ctors) - weight_sum(chunk), chunks);

    quote_append!(tokens,
        _proptest::strategy::TupleUnion::new(( #(#head,)* #tail ))
    );

    struct Recurse<'a>(u32, ::std::slice::Chunks<'a, (u32, Ctor)>);

    impl<'a> ToTokens for Recurse<'a> {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            let (tweight, mut chunks) = (self.0, self.1.clone());

            if let Some(chunk) = chunks.next() {
                if let [(w, c)] = chunk {
                    // Only one element left - no need to nest.
                    quote_append!(tokens, (#w, #c) );
                } else {
                    let head = chunk.iter().map(|(w, c)| quote!( (#w, #c) ));
                    let tail = Recurse(tweight - weight_sum(chunk), chunks);
                    quote_append!(tokens,
                        (#tweight, _proptest::strategy::TupleUnion::new((
                            #(#head,)* #tail
                        )))
                    );
                }
            }
        }
    }

    fn weight_sum(ctors: &[(u32, Ctor)]) -> u32 {
        use std::num::Wrapping;
        let Wrapping(x) = ctors.iter().map(|&(w, _)| Wrapping(w)).sum();
        x
    }
}

/// Tokenizes a weighted list of `Strategy`.
/// For details, see `union_ctor_to_tokens`.
fn union_strat_to_tokens(tokens: &mut TokenStream, strats: &[Strategy]) {
    if strats.is_empty() { return; }

    if let [strat] = strats {
        // This is not a union at all - user provided an enum with one variant.
        strat.to_tokens(tokens);
        return;
    }

    let mut chunks = strats.chunks(UNION_CHUNK_SIZE);
    let chunk = chunks.next().unwrap();
    let head = chunk.iter().map(|s| quote!( (u32, #s) ));
    let tail = Recurse(chunks);

    quote_append!(tokens,
        _proptest::strategy::TupleUnion<( #(#head,)* #tail )>
    );

    struct Recurse<'a>(::std::slice::Chunks<'a, Strategy>);

    impl<'a> ToTokens for Recurse<'a> {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            let mut chunks = self.0.clone();

            if let Some(chunk) = chunks.next() {
                if let [s] = chunk {
                    // Only one element left - no need to nest.
                    quote_append!(tokens, (u32, #s) );
                } else {
                    let head = chunk.iter().map(|s| quote!( (u32, #s) ));
                    let tail = Recurse(chunks);
                    quote_append!(tokens,
                        (u32, _proptest::strategy::TupleUnion<(
                            #(#head,)* #tail
                        )>)
                    );
                }
            }
        }
    }
}

/// Wraps a `Ctor` that expects the `to` "register" to be filled with
/// contents of the `from` register. The correctness of this wrt. the
/// generated Rust code has to be verified externally by checking the
/// construction of the particular `Ctor`.
fn extract(c: Ctor, to: ToReg, from: FromReg) -> Ctor {
    Ctor::Extract(Box::new(c), to, from)
}

/// Construct a `FreshVar` prefixed by `param_`.
fn param<'a>(fv: usize) -> FreshVar<'a> {
    fresh_var("param", fv)
}

//==============================================================================
// MapClosure
//==============================================================================

/// Constructs a `MapClosure` for the given `path` and a list of fields.
pub fn map_closure(path: syn::Path, fs: &[syn::Field]) -> MapClosure {
    MapClosure(path, fs.to_owned())
}

/// A `MapClosure` models the closure part inside a `.prop_map(..)` call.
#[derive(Debug)]
pub struct MapClosure(syn::Path, Vec<syn::Field>);

impl ToTokens for MapClosure {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        fn tmp_var<'a>(idx: usize) -> FreshVar<'a> {
            fresh_var("tmp", idx)
        }

        let MapClosure(path, fields) = self;
        let count = fields.len();
        let tmps = (0..count).map(tmp_var);
        let inits = fields.iter().enumerate().map(|(idx, field)| {
            let tv = tmp_var(idx);
            if let Some(name) = &field.ident {
                quote_spanned!(field.span()=> #name: #tv )
            } else {
                let name = syn::Member::Unnamed(syn::Index::from(idx));
                quote_spanned!(field.span()=> #name: #tv )
            }
        });
        quote_append!(tokens, |( #(#tmps,)* )| #path { #(#inits),* } );
    }
}

//==============================================================================
// FreshVar
//==============================================================================

/// Construct a `FreshVar` with the given `prefix` and the number it has in the
/// count of temporaries for that prefix.
fn fresh_var(prefix: &str, count: usize) -> FreshVar {
    FreshVar { prefix, count }
}

/// A `FreshVar` is an internal implementation detail and models a temporary
/// variable on the stack.
struct FreshVar<'a> {
    prefix: &'a str,
    count: usize
}

impl<'a> ToTokens for FreshVar<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let ident = format!("{}_{}", self.prefix, self.count);
        call_site_ident(&ident).to_tokens(tokens)
    }
}

fn call_site_ident(ident: &str) -> syn::Ident {
    syn::Ident::new(ident, Span::call_site())
}

//==============================================================================
// Util
//==============================================================================

/// A comma separated tuple to a token stream when more than 1, or just flat
/// when 1.
#[derive(Copy, Clone)]
struct Tuple2<S>(S);

impl<'a, T: ToTokens> ToTokens for Tuple2<&'a [T]> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        match self.0 {
            [x] => x.to_tokens(tokens),
            _ => Tuple(self.0).to_tokens(tokens),
        }
    }
}

/// Append a comma separated tuple to a token stream.
struct Tuple<I>(I);

impl<T: ToTokens, I: Clone + IntoIterator<Item = T>> ToTokens for Tuple<I> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let iter = self.0.clone();
        quote_append!(tokens, ( #(#iter),* ) );
    }
}
