jinja: coerce input for string-specific filters (#21370)
This commit is contained in:
parent
887535c33f
commit
1f34806c44
3 changed files with 41 additions and 16 deletions
|
|
@ -306,6 +306,19 @@ value filter_expression::execute_impl(context & ctx) {
|
||||||
filter_id = "strip"; // alias
|
filter_id = "strip"; // alias
|
||||||
}
|
}
|
||||||
JJ_DEBUG("Applying filter '%s' to %s", filter_id.c_str(), input->type().c_str());
|
JJ_DEBUG("Applying filter '%s' to %s", filter_id.c_str(), input->type().c_str());
|
||||||
|
// TODO: Refactor filters so this coercion can be done automatically
|
||||||
|
if (!input->is_undefined() && !is_val<value_string>(input) && (
|
||||||
|
filter_id == "capitalize" ||
|
||||||
|
filter_id == "lower" ||
|
||||||
|
filter_id == "replace" ||
|
||||||
|
filter_id == "strip" ||
|
||||||
|
filter_id == "title" ||
|
||||||
|
filter_id == "upper" ||
|
||||||
|
filter_id == "wordcount"
|
||||||
|
)) {
|
||||||
|
JJ_DEBUG("Coercing %s to String for '%s' filter", input->type().c_str(), filter_id.c_str());
|
||||||
|
input = mk_val<value_string>(input->as_string());
|
||||||
|
}
|
||||||
return try_builtin_func(ctx, filter_id, input)->invoke(func_args(ctx));
|
return try_builtin_func(ctx, filter_id, input)->invoke(func_args(ctx));
|
||||||
|
|
||||||
} else if (is_stmt<call_expression>(filter)) {
|
} else if (is_stmt<call_expression>(filter)) {
|
||||||
|
|
|
||||||
|
|
@ -465,8 +465,9 @@ const func_builtins & value_int_t::get_builtins() const {
|
||||||
double val = static_cast<double>(args.get_pos(0)->as_int());
|
double val = static_cast<double>(args.get_pos(0)->as_int());
|
||||||
return mk_val<value_float>(val);
|
return mk_val<value_float>(val);
|
||||||
}},
|
}},
|
||||||
{"tojson", tojson},
|
{"safe", tojson},
|
||||||
{"string", tojson},
|
{"string", tojson},
|
||||||
|
{"tojson", tojson},
|
||||||
};
|
};
|
||||||
return builtins;
|
return builtins;
|
||||||
}
|
}
|
||||||
|
|
@ -485,8 +486,9 @@ const func_builtins & value_float_t::get_builtins() const {
|
||||||
int64_t val = static_cast<int64_t>(args.get_pos(0)->as_float());
|
int64_t val = static_cast<int64_t>(args.get_pos(0)->as_float());
|
||||||
return mk_val<value_int>(val);
|
return mk_val<value_int>(val);
|
||||||
}},
|
}},
|
||||||
{"tojson", tojson},
|
{"safe", tojson},
|
||||||
{"string", tojson},
|
{"string", tojson},
|
||||||
|
{"tojson", tojson},
|
||||||
};
|
};
|
||||||
return builtins;
|
return builtins;
|
||||||
}
|
}
|
||||||
|
|
@ -771,6 +773,11 @@ const func_builtins & value_string_t::get_builtins() const {
|
||||||
|
|
||||||
|
|
||||||
const func_builtins & value_bool_t::get_builtins() const {
|
const func_builtins & value_bool_t::get_builtins() const {
|
||||||
|
static const func_handler tostring = [](const func_args & args) -> value {
|
||||||
|
args.ensure_vals<value_bool>();
|
||||||
|
bool val = args.get_pos(0)->as_bool();
|
||||||
|
return mk_val<value_string>(val ? "True" : "False");
|
||||||
|
};
|
||||||
static const func_builtins builtins = {
|
static const func_builtins builtins = {
|
||||||
{"default", default_value},
|
{"default", default_value},
|
||||||
{"int", [](const func_args & args) -> value {
|
{"int", [](const func_args & args) -> value {
|
||||||
|
|
@ -783,11 +790,8 @@ const func_builtins & value_bool_t::get_builtins() const {
|
||||||
bool val = args.get_pos(0)->as_bool();
|
bool val = args.get_pos(0)->as_bool();
|
||||||
return mk_val<value_float>(val ? 1.0 : 0.0);
|
return mk_val<value_float>(val ? 1.0 : 0.0);
|
||||||
}},
|
}},
|
||||||
{"string", [](const func_args & args) -> value {
|
{"safe", tostring},
|
||||||
args.ensure_vals<value_bool>();
|
{"string", tostring},
|
||||||
bool val = args.get_pos(0)->as_bool();
|
|
||||||
return mk_val<value_string>(val ? "True" : "False");
|
|
||||||
}},
|
|
||||||
{"tojson", tojson},
|
{"tojson", tojson},
|
||||||
};
|
};
|
||||||
return builtins;
|
return builtins;
|
||||||
|
|
@ -1100,18 +1104,14 @@ const func_builtins & value_object_t::get_builtins() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const func_builtins & value_none_t::get_builtins() const {
|
const func_builtins & value_none_t::get_builtins() const {
|
||||||
|
static const func_handler tostring = [](const func_args &) -> value {
|
||||||
|
return mk_val<value_string>("None");
|
||||||
|
};
|
||||||
static const func_builtins builtins = {
|
static const func_builtins builtins = {
|
||||||
{"default", default_value},
|
{"default", default_value},
|
||||||
{"tojson", tojson},
|
{"tojson", tojson},
|
||||||
{"string", [](const func_args &) -> value {
|
{"string", tostring},
|
||||||
return mk_val<value_string>("None");
|
{"safe", tostring},
|
||||||
}},
|
|
||||||
{"safe", [](const func_args &) -> value {
|
|
||||||
return mk_val<value_string>("None");
|
|
||||||
}},
|
|
||||||
{"strip", [](const func_args &) -> value {
|
|
||||||
return mk_val<value_string>("None");
|
|
||||||
}},
|
|
||||||
{"items", empty_value_fn<value_array>},
|
{"items", empty_value_fn<value_array>},
|
||||||
{"map", empty_value_fn<value_array>},
|
{"map", empty_value_fn<value_array>},
|
||||||
{"reject", empty_value_fn<value_array>},
|
{"reject", empty_value_fn<value_array>},
|
||||||
|
|
|
||||||
|
|
@ -523,6 +523,18 @@ static void test_filters(testing & t) {
|
||||||
"hello"
|
"hello"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_template(t, "upper array",
|
||||||
|
"{{ items|upper }}",
|
||||||
|
{{"items", json::array({"hello", "world"})}},
|
||||||
|
"['HELLO', 'WORLD']"
|
||||||
|
);
|
||||||
|
|
||||||
|
test_template(t, "upper dict",
|
||||||
|
"{{ items|upper }}",
|
||||||
|
{{"items", {{"hello", "world"}}}},
|
||||||
|
"{'HELLO': 'WORLD'}"
|
||||||
|
);
|
||||||
|
|
||||||
test_template(t, "capitalize",
|
test_template(t, "capitalize",
|
||||||
"{{ 'heLlo World'|capitalize }}",
|
"{{ 'heLlo World'|capitalize }}",
|
||||||
json::object(),
|
json::object(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue