blob: 611d058f6718fc435b6187eb42bf0d53ca174c2c [file] [log] [blame]
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))
}
}