import { TypeGuard , isObject , something } from "@opticss/util" ; export interface AndExpression < V extends something > { and : Array < V | BooleanExpression < V > > ; } export interface OrExpression < V extends something > { or : Array < V | BooleanExpression < V > > ; } export interface NotExpression < V extends something > { not : V | BooleanExpression < V > ; } export type BooleanExpression < V extends something > = AndExpression < V > | OrExpression < V > | NotExpression < V > ; export function not < V extends something > ( value ) { return { not : value } ; } export function and < V extends something > ( ... values ) { return { and : values } ; } export function or < V extends something > ( ... values ) { return { or : values } ; } export function isBooleanExpression ( expr ) ; export function isBooleanExpression < T extends something > ( expr , typeGuard ) ; export function isBooleanExpression < T extends something = something > ( expr , typeGuard ? ) { if ( isObject ( expr ) ) { if ( typeGuard ) { return isAndExpression ( expr , typeGuard ) || isOrExpression ( expr , typeGuard ) || isNotExpression ( expr , typeGuard ) ; } else { return isAndExpression ( expr ) || isOrExpression ( expr ) || isNotExpression ( expr ) ; } } else { return false ; } } export function isAndExpression ( expr ) ; export function isAndExpression < V extends something > ( expr , typeGuard ) ; export function isAndExpression < V extends something > ( expr , typeGuard ? ) { let a = ( < Partial < AndExpression < V > > > expr ) . and ; if ( Array . isArray ( a ) ) { if ( typeGuard && a . length > 0 ) { return a . every ( i => isBooleanExpression ( i , typeGuard ) || typeGuard ( i ) ) ; } else { return true ; } } else { return false ; } } export function isOrExpression ( expr ) ; export function isOrExpression < V extends something > ( expr , typeGuard ) ; export function isOrExpression < V extends something > ( expr , typeGuard ? ) { let a = ( < Partial < OrExpression < V > > > expr ) . or ; if ( Array . isArray ( a ) ) { if ( typeGuard && a . length > 0 ) { return a . every ( i => isBooleanExpression ( i , typeGuard ) || typeGuard ( i ) ) ; } else { return true ; } } else { return false ; } } export function isNotExpression ( expr ) ; export function isNotExpression < V extends something > ( expr , typeGuard ) ; export function isNotExpression < V extends something > ( expr , typeGuard ? ) { let notExpr = ( < Partial < NotExpression < V > > > expr ) . not ; if ( typeGuard ) { return isBooleanExpression ( notExpr , typeGuard ) || typeGuard ( notExpr ) ; } else { return notExpr !== undefined ; } }