diff --git a/README.md b/README.md index 29c3193..9d3bd37 100644 --- a/README.md +++ b/README.md @@ -193,6 +193,10 @@ render("{{ divisibleBy(42, 7) }}", data); // true render("{{ max([1, 2, 3]) }}", data); // 3 render("{{ min([-2.4, -1.2, 4.5]) }}", data); // -2.4 +// Convert strings to numbers +render("{{ int(\"2\") == 2 }}", data); // true +render("{{ float(\"1.8\") > 2 }}", data); // false + // Set default values if variables are not defined render("Hello {{ default(neighbour, \"my friend\") }}!", data); // "Hello Peter!" render("Hello {{ default(colleague, \"my friend\") }}!", data); // "Hello my friend!" diff --git a/src/inja.hpp b/src/inja.hpp index 8534eb7..f844fef 100644 --- a/src/inja.hpp +++ b/src/inja.hpp @@ -265,6 +265,8 @@ struct Parsed { DivisibleBy, Even, First, + Float, + Int, Last, Length, Lower, @@ -479,6 +481,12 @@ public: case Parsed::Function::Different: { return eval_expression(element.args[0], data) != eval_expression(element.args[1], data); } + case Parsed::Function::Float: { + return std::stod(eval_expression(element.args[0], data)); + } + case Parsed::Function::Int: { + return std::stoi(eval_expression(element.args[0], data)); + } case Parsed::Function::ReadJson: { try { return data.at(json::json_pointer(element.command)); @@ -655,6 +663,8 @@ public: {Parsed::Function::DivisibleBy, function_regex("divisibleBy", 2)}, {Parsed::Function::Even, function_regex("even", 1)}, {Parsed::Function::First, function_regex("first", 1)}, + {Parsed::Function::Float, function_regex("float", 1)}, + {Parsed::Function::Int, function_regex("int", 1)}, {Parsed::Function::Last, function_regex("last", 1)}, {Parsed::Function::Length, function_regex("length", 1)}, {Parsed::Function::Lower, function_regex("lower", 1)}, diff --git a/test/src/unit-renderer.cpp b/test/src/unit-renderer.cpp index b7da3e1..976bf29 100644 --- a/test/src/unit-renderer.cpp +++ b/test/src/unit-renderer.cpp @@ -164,6 +164,18 @@ TEST_CASE("functions") { // CHECK_THROWS_WITH( env.render("{{ min(name) }}", data), "[inja.exception.json_error] [json.exception.type_error.302] type must be array, but is string" ); } + SECTION("float") { + CHECK( env.render("{{ float(\"2.2\") == 2.2 }}", data) == "true" ); + CHECK( env.render("{{ float(\"-1.25\") == -1.25 }}", data) == "true" ); + // CHECK_THROWS_WITH( env.render("{{ max(name) }}", data), "[inja.exception.json_error] [json.exception.type_error.302] type must be array, but is string" ); + } + + SECTION("int") { + CHECK( env.render("{{ int(\"2\") == 2 }}", data) == "true" ); + CHECK( env.render("{{ int(\"-1.25\") == -1 }}", data) == "true" ); + // CHECK_THROWS_WITH( env.render("{{ max(name) }}", data), "[inja.exception.json_error] [json.exception.type_error.302] type must be array, but is string" ); + } + SECTION("default") { CHECK( env.render("{{ default(11, 0) }}", data) == "11" ); CHECK( env.render("{{ default(nothing, 0) }}", data) == "0" );