From edc14bfc05b47bf6cb34d573381166b882d89077 Mon Sep 17 00:00:00 2001 From: pantor Date: Thu, 16 Nov 2017 22:29:17 +0100 Subject: [PATCH] added write methods, better error messages for functions --- src/inja.hpp | 70 +++++++++++++++++++++------------------- test/src/unit-parser.cpp | 16 ++++----- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/inja.hpp b/src/inja.hpp index 441a028..379bf1d 100644 --- a/src/inja.hpp +++ b/src/inja.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace inja { @@ -424,8 +425,14 @@ public: - json eval_variable(const std::string& input, json data) { - return eval_variable(input, data, true); + template + T eval_variable(const std::string& input, json data) { + const json var = eval_variable(input, data, true); + + if (std::is_same::value) { + return var; + } + return var.get(); } json eval_variable(const std::string& input, json data, bool throw_error) { @@ -435,54 +442,43 @@ public: Match match_function = match(input, get_values(parser.regex_map_functions)); switch ( static_cast(match_function.regex_number()) ) { case Parser::Function::Upper: { - const json str = eval_variable(match_function.str(1), data); - if (not str.is_string()) { throw std::runtime_error("Argument in upper function is not a string."); } - std::string data = str.get(); - std::transform(data.begin(), data.end(), data.begin(), toupper); - return data; + std::string str = eval_variable(match_function.str(1), data); + std::transform(str.begin(), str.end(), str.begin(), toupper); + return str; } case Parser::Function::Lower: { - const json str = eval_variable(match_function.str(1), data); - if (not str.is_string()) { throw std::runtime_error("Argument in lower function is not a string."); } - std::string data = str.get(); - std::transform(data.begin(), data.end(), data.begin(), tolower); - return data; + std::string str = eval_variable(match_function.str(1), data); + std::transform(str.begin(), str.end(), str.begin(), tolower); + return str; } case Parser::Function::Range: { - const json number = eval_variable(match_function.str(1), data); - if (not number.is_number()) { throw std::runtime_error("Argument in range function is not a number."); } - std::vector result(number.get()); + const int number = eval_variable(match_function.str(1), data); + std::vector result(number); std::iota(std::begin(result), std::end(result), 0); return result; } case Parser::Function::Length: { const json list = eval_variable(match_function.str(1), data); - if (not list.is_array()) { throw std::runtime_error("Argument in length function is not a list."); } + if (not list.is_array()) { throw std::runtime_error("[inja.exception.type_error.302] type must be array"); } return list.size(); } case Parser::Function::Round: { - const json number = eval_variable(match_function.str(1), data); - const json precision = eval_variable(match_function.str(2), data); - if (not number.is_number()) { throw std::runtime_error("Argument in round function is not a number."); } - if (not precision.is_number()) { throw std::runtime_error("Argument in round function is not a number."); } - return std::round(number.get() * std::pow(10.0, precision.get())) / std::pow(10.0, precision.get()); + const double number = eval_variable(match_function.str(1), data); + const int precision = eval_variable(match_function.str(2), data); + return std::round(number * std::pow(10.0, precision)) / std::pow(10.0, precision); } case Parser::Function::DivisibleBy: { - const json number = eval_variable(match_function.str(1), data); - const json divisor = eval_variable(match_function.str(2), data); - if (not number.is_number()) { throw std::runtime_error("Argument in divisibleBy function is not a number."); } - if (not divisor.is_number()) { throw std::runtime_error("Argument in divisibleBy function is not a number."); } - return (number.get() % divisor.get() == 0); + const int number = eval_variable(match_function.str(1), data); + const int divisor = eval_variable(match_function.str(2), data); + return (number % divisor == 0); } case Parser::Function::Odd: { - const json number = eval_variable(match_function.str(1), data); - if (not number.is_number()) { throw std::runtime_error("Argument in odd function is not a number."); } - return (number.get() % 2 != 0); + const int number = eval_variable(match_function.str(1), data); + return (number % 2 != 0); } case Parser::Function::Even: { - const json number = eval_variable(match_function.str(1), data); - if (not number.is_number()) { throw std::runtime_error("Argument in even function is not a number."); } - return (number.get() % 2 == 0); + const int number = eval_variable(match_function.str(1), data); + return (number % 2 == 0); } } @@ -643,11 +639,14 @@ public: } void write(const std::string& filename, json data, const std::string& filename_out) { - + std::ofstream file(global_path + filename_out); + file << render_template_with_json_file(filename, data); + file.close(); } void write(const std::string& filename, const std::string& filename_data, const std::string& filename_out) { - + json data = load_json(filename_data); + write(filename, data, filename_out); } std::string load_file(const std::string& filename) { @@ -664,6 +663,9 @@ public: } }; +/*! +@brief render with default settings +*/ inline std::string render(const std::string& input, json data) { return Environment().render(input, data); } diff --git a/test/src/unit-parser.cpp b/test/src/unit-parser.cpp index 05cbfac..722bcba 100644 --- a/test/src/unit-parser.cpp +++ b/test/src/unit-parser.cpp @@ -232,47 +232,47 @@ TEST_CASE("Parse functions") { SECTION("Upper") { CHECK( env.eval_variable("upper(name)", data) == "PETER" ); CHECK( env.eval_variable("upper(city)", data) == "NEW YORK" ); - CHECK_THROWS_WITH( env.eval_variable("upper(5)", data), "Argument in upper function is not a string." ); + CHECK_THROWS_WITH( env.eval_variable("upper(5)", data), "[json.exception.type_error.302] type must be string, but is number" ); } SECTION("Lower") { CHECK( env.eval_variable("lower(name)", data) == "peter" ); CHECK( env.eval_variable("lower(city)", data) == "new york" ); - CHECK_THROWS_WITH( env.eval_variable("lower(5)", data), "Argument in lower function is not a string." ); + CHECK_THROWS_WITH( env.eval_variable("lower(5.45)", data), "[json.exception.type_error.302] type must be string, but is number" ); } SECTION("Range") { CHECK( env.eval_variable("range(4)", data) == std::vector({0, 1, 2, 3}) ); - CHECK_THROWS_WITH( env.eval_variable("range(true)", data), "Argument in range function is not a number." ); + CHECK_THROWS_WITH( env.eval_variable("range(name)", data), "[json.exception.type_error.302] type must be number, but is string" ); } SECTION("Length") { CHECK( env.eval_variable("length(names)", data) == 4 ); - CHECK_THROWS_WITH( env.eval_variable("length(5)", data), "Argument in length function is not a list." ); + CHECK_THROWS_WITH( env.eval_variable("length(5)", data), "[inja.exception.type_error.302] type must be array" ); } SECTION("Round") { CHECK( env.eval_variable("round(4, 0)", data) == 4 ); CHECK( env.eval_variable("round(temperature, 2)", data) == 25.68 ); - CHECK_THROWS_WITH( env.eval_variable("round(name, 2)", data), "Argument in round function is not a number." ); + CHECK_THROWS_WITH( env.eval_variable("round(name, 2)", data), "[json.exception.type_error.302] type must be number, but is string" ); } SECTION("DivisibleBy") { CHECK( env.eval_variable("divisibleBy(50, 5)", data) == true ); CHECK( env.eval_variable("divisibleBy(12, 3)", data) == true ); CHECK( env.eval_variable("divisibleBy(11, 3)", data) == false ); - CHECK_THROWS_WITH( env.eval_variable("divisibleBy(name, 2)", data), "Argument in divisibleBy function is not a number." ); + CHECK_THROWS_WITH( env.eval_variable("divisibleBy(name, 2)", data), "[json.exception.type_error.302] type must be number, but is string" ); } SECTION("Odd") { CHECK( env.eval_variable("odd(11)", data) == true ); CHECK( env.eval_variable("odd(12)", data) == false ); - CHECK_THROWS_WITH( env.eval_variable("odd(name)", data), "Argument in odd function is not a number." ); + CHECK_THROWS_WITH( env.eval_variable("odd(name)", data), "[json.exception.type_error.302] type must be number, but is string" ); } SECTION("Even") { CHECK( env.eval_variable("even(11)", data) == false ); CHECK( env.eval_variable("even(12)", data) == true ); - CHECK_THROWS_WITH( env.eval_variable("even(name)", data), "Argument in even function is not a number." ); + CHECK_THROWS_WITH( env.eval_variable("even(name)", data), "[json.exception.type_error.302] type must be number, but is string" ); } }