Skip to content

Instantly share code, notes, and snippets.

@giautm
Last active September 23, 2017 07:41
Show Gist options
  • Save giautm/65b744433e9b10ebd58afd0a5b06bc19 to your computer and use it in GitHub Desktop.
Save giautm/65b744433e9b10ebd58afd0a5b06bc19 to your computer and use it in GitHub Desktop.
export class SpecAsync {
async isSatisfiedBy(obj) {
return Promise.reject('isSatisfiedBy not implemented');
}
and(spec) {
return new AndSpecAsync(this, spec);
}
or(spec) {
return new OrSpecAsync(this, spec);
}
not() {
return new NotSpecAsync(this);
}
}
export class FuncSpecAsync extends SpecAsync {
constructor(funcAsync) {
super();
this.funcAsync = funcAsync;
}
async isSatisfiedBy(obj) {
if (this.funcAsync) {
return this.funcAsync(obj);
}
return super.isSatisfiedBy(obj);
}
}
export class AndSpecAsync extends SpecAsync {
constructor(lhs, rhs) {
super();
this.lhs = lhs;
this.rhs = rhs;
}
async isSatisfiedBy(obj) {
if (this.lhs && this.lhs.isSatisfiedBy) {
const l = await this.lhs.isSatisfiedBy(obj);
if (l && this.rhs && this.rhs.isSatisfiedBy) {
return this.rhs.isSatisfiedBy(obj);
}
}
return Promise.resolve(false);
}
}
export class OrSpecAsync extends SpecAsync {
constructor(lhs, rhs) {
super();
this.lhs = lhs;
this.rhs = rhs;
}
async isSatisfiedBy(obj) {
if (this.lhs && this.lhs.isSatisfiedBy) {
const l = await this.lhs.isSatisfiedBy(obj);
if (l) {
return l;
} else if (this.rhs && this.rhs.isSatisfiedBy) {
return this.rhs.isSatisfiedBy(obj);
}
}
return Promise.resolve(false);
}
}
export class NotSpecAsync extends SpecAsync {
constructor(spec) {
super();
this.spec = spec;
}
async isSatisfiedBy(obj) {
if (this.spec && this.spec.isSatisfiedBy) {
const value = await this.spec.isSatisfiedBy(obj);
return !value;
}
return super.isSatisfiedBy(obj);
}
}
export default SpecAsync;
export class Spec {
isSatisfiedBy(obj) {
throw new Error('isSatisfiedBy not implemented');
}
and(spec) {
return new AndSpec(this, spec);
}
or(spec) {
return new OrSpec(this, spec);
}
not() {
return new NotSpec(this);
}
}
export class FuncSpec extends Spec {
constructor(func) {
super();
this.func = func;
}
isSatisfiedBy(obj) {
if (this.func) {
return this.func(obj);
}
return super.isSatisfiedBy(obj);
}
}
export class AndSpec extends Spec {
constructor(lhs, rhs) {
super();
this.lhs = lhs;
this.rhs = rhs;
}
isSatisfiedBy(obj) {
if (this.lhs && this.lhs.isSatisfiedBy) {
const l = this.lhs.isSatisfiedBy(obj);
if (l && this.rhs && this.rhs.isSatisfiedBy) {
return this.rhs.isSatisfiedBy(obj);
}
}
return false;
}
}
export class OrSpec extends Spec {
constructor(lhs, rhs) {
super();
this.lhs = lhs;
this.rhs = rhs;
}
isSatisfiedBy(obj) {
if (this.lhs && this.lhs.isSatisfiedBy) {
const l = this.lhs.isSatisfiedBy(obj);
if (l) {
return l;
} else if (this.rhs && this.rhs.isSatisfiedBy) {
return this.rhs.isSatisfiedBy(obj);
}
}
return false;
}
}
export class NotSpec extends Spec {
constructor(spec) {
super();
this.spec = spec;
}
isSatisfiedBy(obj) {
if (this.spec && this.spec.isSatisfiedBy) {
const value = this.spec.isSatisfiedBy(obj);
return !value;
}
return super.isSatisfiedBy(obj);
}
}
export default Spec;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment