import { Parser, Result, Input, Output } from '../parser';
import { always } from '../control/state';
import { tester } from '../delimiter';
export function contract
(patterns: string | RegExp, parser: P, cond: (input: Parser.Input
, output: Output>) => boolean): P;
export function contract(precond: (input: Parser.Input
, output: Output>) => boolean, parser: P, postcond: (input: Parser.Input, output: Output>) => boolean): P;
export function contract(precond: string | RegExp | ((input: Input, output: Output) => boolean), parser: Parser, postcond: (input: Input, output: Output) => boolean): Parser {
if (typeof precond !== 'function') {
precond = tester(precond, false);
}
return validate(precond, verify(parser, postcond));
}
export function validate(pattern: string | RegExp, parser: P): P;
export function validate
(cond: (input: Parser.Input
, output: Output>) => boolean, parser: P): P;
export function validate(cond: string | RegExp | ((input: Input, output: Output) => boolean), parser: Parser): Parser {
if (typeof cond !== 'function') {
cond = tester(cond, false);
}
return always([
(input, output) =>
output.state && cond(input, output) ? output.context : Result.skip,
parser,
]);
}
export function verify(parser: P, cond: (input: Parser.Input
, output: Output>) => boolean): P;
export function verify(parser: Parser, cond: (input: Input, output: Output) => boolean): Parser {
assert(parser);
return always([
parser,
(input, output) =>
output.state && cond(input, output) ? output.context : Result.fail,
]);
}