Skip to content

Commit 48666b3

Browse files
committed
refactor: consolidate selectattr and rejectattr logic
1 parent a144498 commit 48666b3

File tree

1 file changed

+7
-40
lines changed

1 file changed

+7
-40
lines changed

packages/jinja/src/runtime.ts

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -613,46 +613,15 @@ export class Interpreter {
613613

614614
if (operand instanceof ArrayValue) {
615615
switch (filterName) {
616-
case "selectattr": {
617-
if (operand.value.some((x) => !(x instanceof ObjectValue))) {
618-
throw new Error("`selectattr` can only be applied to array of objects");
619-
}
620-
if (filter.args.some((x) => x.type !== "StringLiteral")) {
621-
throw new Error("arguments of `selectattr` must be strings");
622-
}
623-
624-
const [attr, testName, value] = filter.args.map((x) => this.evaluate(x, environment)) as StringValue[];
625-
626-
let testFunction: (...x: AnyRuntimeValue[]) => boolean;
627-
if (testName) {
628-
// Get the test function from the environment
629-
const test = environment.tests.get(testName.value);
630-
if (!test) {
631-
throw new Error(`Unknown test: ${testName.value}`);
632-
}
633-
testFunction = test;
634-
} else {
635-
// Default to truthiness of first argument
636-
testFunction = (...x: AnyRuntimeValue[]) => x[0].__bool__().value;
637-
}
638-
639-
// Filter the array using the test function
640-
const filtered = (operand.value as ObjectValue[]).filter((item) => {
641-
const a = item.value.get(attr.value);
642-
if (a) {
643-
return testFunction(a, value);
644-
}
645-
return false;
646-
});
647-
648-
return new ArrayValue(filtered);
649-
}
616+
case "selectattr":
650617
case "rejectattr": {
618+
const select = filterName === "selectattr";
619+
651620
if (operand.value.some((x) => !(x instanceof ObjectValue))) {
652-
throw new Error("`rejectattr` can only be applied to array of objects");
621+
throw new Error(`\`${filterName}\` can only be applied to array of objects`);
653622
}
654623
if (filter.args.some((x) => x.type !== "StringLiteral")) {
655-
throw new Error("arguments of `rejectattr` must be strings");
624+
throw new Error(`arguments of \`${filterName}\` must be strings`);
656625
}
657626

658627
const [attr, testName, value] = filter.args.map((x) => this.evaluate(x, environment)) as StringValue[];
@@ -673,10 +642,8 @@ export class Interpreter {
673642
// Filter the array using the test function
674643
const filtered = (operand.value as ObjectValue[]).filter((item) => {
675644
const a = item.value.get(attr.value);
676-
if (a) {
677-
return !testFunction(a, value);
678-
}
679-
return true;
645+
const result = a ? testFunction(a, value) : false;
646+
return select ? result : !result;
680647
});
681648

682649
return new ArrayValue(filtered);

0 commit comments

Comments
 (0)