Filter fixes

This commit is contained in:
Zoe Roux 2024-12-22 18:42:26 +01:00
parent 81b7d5558e
commit e20e327286
No known key found for this signature in database

View File

@ -20,6 +20,7 @@ import {
qthen, qthen,
later, later,
between, between,
recover,
} from "parjs/combinators"; } from "parjs/combinators";
import type { KError } from "../error"; import type { KError } from "../error";
@ -46,8 +47,8 @@ function t<T>(parser: Parjser<T>): Parjser<T> {
return parser.pipe(thenq(string(" ").pipe(many()))); return parser.pipe(thenq(string(" ").pipe(many())));
} }
const str = t(noCharOf(" ")).pipe(many1(), stringify()).expects("a string"); const str = t(noCharOf(" ").pipe(many1(), stringify()).expects("a string"));
const enumP = t(letter()).pipe(many1(), stringify()).expects("an enum value"); const enumP = t(letter().pipe(many1(), stringify()).expects("an enum value"));
const property = str.expects("a property"); const property = str.expects("a property");
@ -58,26 +59,35 @@ const floatVal = t(
const dateVal = t( const dateVal = t(
digit(10).pipe( digit(10).pipe(
exactly(4), exactly(4),
stringify(),
thenq(string("-")), thenq(string("-")),
then( then(
digit(10).pipe(exactly(2), thenq(string("-"))), digit(10).pipe(exactly(2), stringify(), thenq(string("-"))),
digit(10).pipe(exactly(2)), digit(10).pipe(exactly(2), stringify()),
), ),
map(([year, month, day]) => ({ map(([year, month, day]) => ({
type: "date" as const, type: "date" as const,
value: `${year}-${month}-${day}`, value: `${year}-${month}-${day}`,
})), })),
), ),
).expects("a date");
const strVal = str.pipe(
between('"'),
or(str.pipe(between("'"))),
map((s) => ({ type: "string" as const, value: s })),
); );
const strVal = str.pipe(map((s) => ({ type: "string" as const, value: s })));
const enumVal = enumP.pipe(map((e) => ({ type: "enum" as const, value: e }))); const enumVal = enumP.pipe(map((e) => ({ type: "enum" as const, value: e })));
const value = intVal const value = dateVal
.pipe(or(floatVal, dateVal, strVal, enumVal)) .pipe(
// until we get the `-` character, this could be an int or a float.
recover(() => ({ kind: "Soft" })),
or(intVal, floatVal, strVal, enumVal),
)
.expects("a valid value"); .expects("a valid value");
const operator = t(anyStringOf(...operators)).expects("an operator"); const operator = t(anyStringOf(...operators)).expects("an operator");
const operation = property export const operation = property
.pipe( .pipe(
then(operator, value), then(operator, value),
map(([property, operator, value]) => ({ map(([property, operator, value]) => ({
@ -89,7 +99,7 @@ const operation = property
) )
.expects("an operation"); .expects("an operation");
export const expression = later<Expression>(); const expression = later<Expression>();
const not = t(string("not")).pipe( const not = t(string("not")).pipe(
qthen(expression), qthen(expression),
@ -110,6 +120,8 @@ expression.init(
not.pipe(or(operation, expression.pipe(or(andor), between("(", ")")))), not.pipe(or(operation, expression.pipe(or(andor), between("(", ")")))),
); );
export const filterParser = andor.pipe(or(expression));
export const parseFilter = ( export const parseFilter = (
filter: string, filter: string,
config: Filter, config: Filter,