export abstract class AsyncBooleanExpression { abstract evaluate( t:T ):Promise; NOT():AsyncBooleanExpression { return new NotAsyncExpression( this ); } AND( matcher:AsyncBooleanExpression):AsyncBooleanExpression { return new AndAsyncExpression( [ this, matcher ] ); } OR( matcher:AsyncBooleanExpression):AsyncBooleanExpression { return new OrAsyncExpression( [ this, matcher ] ); } } export class NotAsyncExpression extends AsyncBooleanExpression { private _matcher:AsyncBooleanExpression; constructor( matcher:AsyncBooleanExpression ) { super(); this._matcher = matcher; } async evaluate( t:T ):Promise { let result = await this._matcher.evaluate( t ); return Promise.resolve( ! result ); } NOT() { return this._matcher; } } export abstract class ListInputAsyncExpression extends AsyncBooleanExpression { protected _matchers:AsyncBooleanExpression[]; constructor( matchers:AsyncBooleanExpression[] ) { super(); this._matchers = matchers; } } export class AndAsyncExpression extends ListInputAsyncExpression { async evaluate( t:T ):Promise { for ( let matcher of this._matchers ) { let result = await matcher.evaluate( t ); if ( ! result ) { return Promise.resolve( false ); } } return Promise.resolve( true ); } AND( matcher:AsyncBooleanExpression ) { this._matchers.push( matcher ); return this; } } export class OrAsyncExpression extends ListInputAsyncExpression { async evaluate( t:T ):Promise { for ( let matcher of this._matchers ) { let result = await matcher.evaluate( t ); if ( result ) { return Promise.resolve( true ); } } return Promise.resolve( false ); } OR( matcher:AsyncBooleanExpression ) { this._matchers.push( matcher ); return this; } }