import { TypeGuard, isObject, something } from "@opticss/util"; export interface AndExpression { and: Array>; } export interface OrExpression { or: Array>; } export interface NotExpression { not: V | BooleanExpression; } export type BooleanExpression = AndExpression | OrExpression | NotExpression; export function not(value: V | BooleanExpression): NotExpression { return {not: value}; } export function and(...values: Array>): AndExpression { return {and: values}; } export function or(...values: Array>): OrExpression { return {or: values}; } export function isBooleanExpression(expr: unknown): expr is BooleanExpression; export function isBooleanExpression(expr: unknown, typeGuard: TypeGuard): expr is BooleanExpression; export function isBooleanExpression(expr: unknown, typeGuard?: TypeGuard): expr is BooleanExpression { 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: Partial>): expr is AndExpression; export function isAndExpression(expr: Partial>, typeGuard: TypeGuard): expr is AndExpression; export function isAndExpression(expr: Partial>, typeGuard?: TypeGuard): expr is AndExpression { let a = (>>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: Partial>): expr is OrExpression; export function isOrExpression(expr: Partial>, typeGuard: TypeGuard): expr is OrExpression; export function isOrExpression(expr: Partial>, typeGuard?: TypeGuard): expr is OrExpression { let a = (>>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: Partial>): expr is NotExpression; export function isNotExpression(expr: Partial>, typeGuard: TypeGuard): expr is NotExpression; export function isNotExpression(expr: Partial>, typeGuard?: TypeGuard): expr is NotExpression { let notExpr = (>>expr).not; if (typeGuard) { return isBooleanExpression(notExpr, typeGuard) || typeGuard(notExpr); } else { return notExpr !== undefined; } }