syn 0.7.1

Nom parser for Rust items
Documentation
use {
    Ident,
    Lifetime,
    LifetimeDef,
    Ty,
    TyParamBound,
    WhereBoundPredicate,
    WherePredicate,
    WhereRegionPredicate,
};
use aster::invoke::{Invoke, Identity};
use aster::lifetime::{IntoLifetime, IntoLifetimeDef, LifetimeDefBuilder};
use aster::path::IntoPath;
use aster::ty::TyBuilder;
use aster::ty_param::{TyParamBoundBuilder, PolyTraitRefBuilder, TraitTyParamBoundBuilder};

//////////////////////////////////////////////////////////////////////////////

pub struct WherePredicateBuilder<F=Identity> {
    callback: F,
}

impl WherePredicateBuilder {
    pub fn new() -> Self {
        WherePredicateBuilder::with_callback(Identity)
    }
}

impl<F> WherePredicateBuilder<F>
    where F: Invoke<WherePredicate>,
{
    pub fn with_callback(callback: F) -> Self {
        WherePredicateBuilder {
            callback: callback,
        }
    }

    pub fn bound(self) -> TyBuilder<Self> {
        TyBuilder::with_callback(self)
    }

    pub fn lifetime<L>(self, lifetime: L) -> WhereRegionPredicateBuilder<F>
        where L: IntoLifetime,
    {
        WhereRegionPredicateBuilder {
            callback: self.callback,
            lifetime: lifetime.into_lifetime(),
            bounds: Vec::new(),
        }
    }
}

impl<F> Invoke<Ty> for WherePredicateBuilder<F>
    where F: Invoke<WherePredicate>,
{
    type Result = WhereBoundPredicateTyBuilder<F>;

    fn invoke(self, ty: Ty) -> Self::Result {
        WhereBoundPredicateTyBuilder {
            callback: self.callback,
            ty: ty,
            bound_lifetimes: Vec::new(),
        }
    }
}

//////////////////////////////////////////////////////////////////////////////

pub struct WhereBoundPredicateBuilder<F> {
    callback: F,
}

impl<F> Invoke<Ty> for WhereBoundPredicateBuilder<F>
    where F: Invoke<WherePredicate>,
{
    type Result = WhereBoundPredicateTyBuilder<F>;

    fn invoke(self, ty: Ty) -> Self::Result {
        WhereBoundPredicateTyBuilder {
            callback: self.callback,
            ty: ty,
            bound_lifetimes: Vec::new(),
        }
    }
}

//////////////////////////////////////////////////////////////////////////////

pub struct WhereBoundPredicateTyBuilder<F> {
    callback: F,
    ty: Ty,
    bound_lifetimes: Vec<LifetimeDef>,
}

impl<F> WhereBoundPredicateTyBuilder<F>
    where F: Invoke<WherePredicate>,
{
    pub fn with_for_lifetime<L>(mut self, lifetime: L) -> Self
        where L: IntoLifetimeDef,
    {
        self.bound_lifetimes.push(lifetime.into_lifetime_def());
        self
    }

    pub fn for_lifetime<N>(self, name: N) -> LifetimeDefBuilder<Self>
        where N: Into<Ident>,
    {
        LifetimeDefBuilder::with_callback(name, self)
    }

    pub fn with_bound(self, bound: TyParamBound) -> WhereBoundPredicateTyBoundsBuilder<F> {
        WhereBoundPredicateTyBoundsBuilder {
            callback: self.callback,
            ty: self.ty,
            bound_lifetimes: self.bound_lifetimes,
            bounds: vec![bound],
        }
    }

    pub fn bound(self) -> TyParamBoundBuilder<WhereBoundPredicateTyBoundsBuilder<F>> {
        let builder = WhereBoundPredicateTyBoundsBuilder {
            callback: self.callback,
            ty: self.ty,
            bound_lifetimes: self.bound_lifetimes,
            bounds: vec![],
        };
        TyParamBoundBuilder::with_callback(builder)
    }

    pub fn trait_<P>(self, path: P)
        -> PolyTraitRefBuilder<
            TraitTyParamBoundBuilder<
                WhereBoundPredicateTyBoundsBuilder<F>
            >
        >
        where P: IntoPath,
    {
        self.bound().trait_(path)
    }

    pub fn lifetime<L>(self, lifetime: L) -> WhereBoundPredicateTyBoundsBuilder<F>
        where L: IntoLifetime,
    {
        self.bound().lifetime(lifetime)
    }
}

impl<F> Invoke<LifetimeDef> for WhereBoundPredicateTyBuilder<F>
    where F: Invoke<WherePredicate>,
{
    type Result = Self;

    fn invoke(self, lifetime: LifetimeDef) -> Self {
        self.with_for_lifetime(lifetime)
    }
}

impl<F> Invoke<TyParamBound> for WhereBoundPredicateTyBuilder<F>
    where F: Invoke<WherePredicate>,
{
    type Result = WhereBoundPredicateTyBoundsBuilder<F>;

    fn invoke(self, bound: TyParamBound) -> Self::Result {
        self.with_bound(bound)
    }
}

//////////////////////////////////////////////////////////////////////////////

pub struct WhereBoundPredicateTyBoundsBuilder<F> {
    callback: F,
    ty: Ty,
    bound_lifetimes: Vec<LifetimeDef>,
    bounds: Vec<TyParamBound>,
}

impl<F> WhereBoundPredicateTyBoundsBuilder<F>
    where F: Invoke<WherePredicate>,
{
    pub fn with_for_lifetime<L>(mut self, lifetime: L) -> Self
        where L: IntoLifetimeDef,
    {
        self.bound_lifetimes.push(lifetime.into_lifetime_def());
        self
    }

    pub fn for_lifetime<N>(self, name: N) -> LifetimeDefBuilder<Self>
        where N: Into<Ident>,
    {
        LifetimeDefBuilder::with_callback(name, self)
    }

    pub fn with_bound(mut self, bound: TyParamBound) -> Self {
        self.bounds.push(bound);
        self
    }

    pub fn bound(self) -> TyParamBoundBuilder<Self> {
        TyParamBoundBuilder::with_callback(self)
    }

    pub fn trait_<P>(self, path: P)
        -> PolyTraitRefBuilder<TraitTyParamBoundBuilder<Self>>
        where P: IntoPath,
    {
        self.bound().trait_(path)
    }

    pub fn lifetime<L>(self, lifetime: L) -> Self
        where L: IntoLifetime,
    {
        self.bound().lifetime(lifetime)
    }

    pub fn build(self) -> F::Result {
        let predicate = WhereBoundPredicate {
            bound_lifetimes: self.bound_lifetimes,
            bounded_ty: self.ty,
            bounds: self.bounds,
        };

        self.callback.invoke(WherePredicate::BoundPredicate(predicate))
    }
}

impl<F> Invoke<LifetimeDef> for WhereBoundPredicateTyBoundsBuilder<F>
    where F: Invoke<WherePredicate>,
{
    type Result = Self;

    fn invoke(self, lifetime: LifetimeDef) -> Self {
        self.with_for_lifetime(lifetime)
    }
}

impl<F> Invoke<TyParamBound> for WhereBoundPredicateTyBoundsBuilder<F>
    where F: Invoke<WherePredicate>,
{
    type Result = Self;

    fn invoke(self, bound: TyParamBound) -> Self {
        self.with_bound(bound)
    }
}

//////////////////////////////////////////////////////////////////////////////

pub struct WhereRegionPredicateBuilder<F> {
    callback: F,
    lifetime: Lifetime,
    bounds: Vec<Lifetime>,
}

impl<F> WhereRegionPredicateBuilder<F>
    where F: Invoke<WherePredicate>,
{
    pub fn bound<L>(mut self, lifetime: L) -> Self
        where L: IntoLifetime,
    {
        self.bounds.push(lifetime.into_lifetime());
        self
    }

    pub fn build(self) -> F::Result {
        let predicate = WhereRegionPredicate {
            lifetime: self.lifetime,
            bounds: self.bounds,
        };

        self.callback.invoke(WherePredicate::RegionPredicate(predicate))
    }
}