add replace function (#306)

Co-authored-by: Felix Maier <fm41@mailbox.org>
This commit is contained in:
Felix Maier
2025-09-06 16:38:04 +02:00
committed by GitHub
parent 593ff96024
commit 2d6b382e2a
5 changed files with 24 additions and 0 deletions

View File

@@ -212,6 +212,9 @@ render("Hello {{ upper(neighbour) }}!", data); // "Hello PETER!"
render("Hello {{ lower(neighbour) }}!", data); // "Hello peter!"
render("Hello {{ capitalize(neighbour) }}!", data); // "Hello Peter!"
// Replace characters in a string
render("{{ replace(neighbour, \"e\", \"3\")}}", data); // "P3t3r"
// Range function, useful for loops
render("{% for i in range(4) %}{{ loop.index1 }}{% endfor %}", data); // "1234"
render("{% for i in range(3) %}{{ at(guests, i) }} {% endfor %}", data); // "Jeff Tom Patrick "

View File

@@ -63,6 +63,7 @@ public:
Min,
Odd,
Range,
Replace,
Round,
Sort,
Upper,
@@ -106,6 +107,7 @@ private:
{std::make_pair("min", 1), FunctionData {Operation::Min}},
{std::make_pair("odd", 1), FunctionData {Operation::Odd}},
{std::make_pair("range", 1), FunctionData {Operation::Range}},
{std::make_pair("replace", 3), FunctionData {Operation::Replace}},
{std::make_pair("round", 2), FunctionData {Operation::Round}},
{std::make_pair("sort", 1), FunctionData {Operation::Sort}},
{std::make_pair("upper", 1), FunctionData {Operation::Upper}},

View File

@@ -414,6 +414,12 @@ class Renderer : public NodeVisitor {
std::iota(result.begin(), result.end(), 0);
make_result(std::move(result));
} break;
case Op::Replace: {
const auto args = get_arguments<3>(node);
auto result = args[0]->get<std::string>();
replace_substring(result, args[1]->get<std::string>(), args[2]->get<std::string>());
make_result(std::move(result));
} break;
case Op::Round: {
const auto args = get_arguments<2>(node);
const auto precision = args[1]->get<const json::number_integer_t>();

View File

@@ -170,6 +170,7 @@ public:
Min,
Odd,
Range,
Replace,
Round,
Sort,
Upper,
@@ -213,6 +214,7 @@ private:
{std::make_pair("min", 1), FunctionData {Operation::Min}},
{std::make_pair("odd", 1), FunctionData {Operation::Odd}},
{std::make_pair("range", 1), FunctionData {Operation::Range}},
{std::make_pair("replace", 3), FunctionData {Operation::Replace}},
{std::make_pair("round", 2), FunctionData {Operation::Round}},
{std::make_pair("sort", 1), FunctionData {Operation::Sort}},
{std::make_pair("upper", 1), FunctionData {Operation::Upper}},
@@ -2521,6 +2523,12 @@ class Renderer : public NodeVisitor {
std::iota(result.begin(), result.end(), 0);
make_result(std::move(result));
} break;
case Op::Replace: {
const auto args = get_arguments<3>(node);
auto result = args[0]->get<std::string>();
replace_substring(result, args[1]->get<std::string>(), args[2]->get<std::string>());
make_result(std::move(result));
} break;
case Op::Round: {
const auto args = get_arguments<2>(node);
const auto precision = args[1]->get<const json::number_integer_t>();

View File

@@ -108,6 +108,11 @@ TEST_CASE("functions") {
// [json.exception.type_error.302] type must be array, but is number" );
}
SUBCASE("replace") {
CHECK(env.render("{{ replace(name, \"e\", \"3\") }}", data) == "P3t3r");
CHECK(env.render("{{ replace(city, \" \", \"_\") }}", data) == "New_York");
}
SUBCASE("round") {
CHECK(env.render("{{ round(4, 0) }}", data) == "4");
CHECK(env.render("{{ round(temperature, 2) }}", data) == "25.68");