From 0f062f4da180198142b04222b00019e6da114288 Mon Sep 17 00:00:00 2001 From: Anthony DePasquale Date: Tue, 1 Oct 2024 19:10:02 +0200 Subject: [PATCH] Handle left StringValue with right ObjectValue --- Sources/Runtime.swift | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Sources/Runtime.swift b/Sources/Runtime.swift index 6a4f54f..6eceb7f 100644 --- a/Sources/Runtime.swift +++ b/Sources/Runtime.swift @@ -428,7 +428,20 @@ struct Interpreter { } if left is StringValue, right is ObjectValue { - throw JinjaError.syntaxNotSupported + switch node.operation.value { + case "in": + if let leftString = (left as? StringValue)?.value, + let rightObject = right as? ObjectValue { + return BooleanValue(value: rightObject.value.keys.contains(leftString)) + } + case "not in": + if let leftString = (left as? StringValue)?.value, + let rightObject = right as? ObjectValue { + return BooleanValue(value: !rightObject.value.keys.contains(leftString)) + } + default: + throw JinjaError.runtime("Unsupported operation '\(node.operation.value)' between StringValue and ObjectValue") + } } throw JinjaError.syntax( @@ -664,6 +677,17 @@ struct Interpreter { throw JinjaError.runtime("Unknown filter: \(node.filter)") } + func evaluateTestExpression(node: TestExpression, environment: Environment) throws -> any RuntimeValue { + let operand = try self.evaluate(statement: node.operand, environment: environment) + + if let testFunction = environment.tests[node.test.value] { + let result = try testFunction(operand) + return BooleanValue(value: node.negate ? !result : result) + } else { + throw JinjaError.runtime("Unknown test: \(node.test.value)") + } + } + func evaluate(statement: Statement?, environment: Environment) throws -> any RuntimeValue { if let statement { switch statement { @@ -693,6 +717,8 @@ struct Interpreter { return BooleanValue(value: statement.value) case let statement as FilterExpression: return try self.evaluateFilterExpression(node: statement, environment: environment) + case let statement as TestExpression: + return try self.evaluateTestExpression(node: statement, environment: environment) case is NullLiteral: return NullValue() default: