Skip to content

Commit b11bdd6

Browse files
committed
feat(Handlebars): concat helper variadic arguments
1 parent 826295c commit b11bdd6

File tree

1 file changed

+59
-27
lines changed

1 file changed

+59
-27
lines changed

src/lib/Support/Handlebars.cpp

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4014,48 +4014,80 @@ at_fn(dom::Value range, dom::Value field, dom::Value options)
40144014
}
40154015
}
40164016

4017-
dom::Value
4018-
concat_fn(
4019-
dom::Value range1,
4020-
dom::Value sep,
4021-
dom::Value range2,
4022-
dom::Value options)
4017+
Expected<dom::Value>
4018+
concat_fn(dom::Array const& arguments)
40234019
{
4024-
auto isBlock = options.isUndefined() && static_cast<bool>(range2.get("fn"));
4020+
dom::Value options = arguments.back();
4021+
dom::Value fn = options.get("fn");
4022+
auto const isBlock = static_cast<bool>(fn);
40254023
if (isBlock)
40264024
{
4027-
options = range2;
4028-
range2 = sep;
4029-
sep = range1;
4030-
range1 = options.get("fn")();
4025+
// Block overload: concatenate the contents of the
4026+
// block with the contents of the arguments as strings.
4027+
std::string str = static_cast<std::string>(fn());
4028+
for (std::size_t i = 0; i < arguments.size() - 1; ++i)
4029+
{
4030+
str += toString(arguments.get(i));
4031+
}
4032+
return str;
40314033
}
40324034

4033-
if (range1.isString() || range2.isString())
4035+
// Check if we have at least one argument besides the options
4036+
if (arguments.size() == 1)
40344037
{
4035-
return range1 + sep + range2;
4038+
return Unexpected(Error("#concat requires at least one argument"));
40364039
}
4037-
else if (range1.isArray() && sep.isArray())
4040+
4041+
dom::Value firstArg = arguments.get(0);
4042+
4043+
// Array overload: concatenate all arguments a single array.
4044+
if (firstArg.isArray())
40384045
{
4039-
options = range2;
4040-
range2 = sep;
40414046
dom::Array res;
4042-
for (dom::Value item : range1.getArray())
4047+
for (std::size_t i = 0; i < arguments.size() - 1; ++i)
40434048
{
4044-
res.emplace_back(item);
4049+
dom::Value arg = arguments.get(i);
4050+
if (arg.isArray())
4051+
{
4052+
for (dom::Value item : arg.getArray())
4053+
{
4054+
res.emplace_back(item);
4055+
}
4056+
}
4057+
else
4058+
{
4059+
res.emplace_back(arg);
4060+
}
40454061
}
4046-
for (dom::Value item : range2.getArray())
4062+
return res;
4063+
}
4064+
4065+
// Object overload: concatenate all arguments into a single object.
4066+
if (firstArg.isObject())
4067+
{
4068+
dom::Object res = firstArg.getObject();
4069+
for (std::size_t i = 1; i < arguments.size() - 1; ++i)
40474070
{
4048-
res.emplace_back(item);
4071+
dom::Value arg = arguments.get(i);
4072+
if (arg.isObject())
4073+
{
4074+
res = createFrame(arg.getObject(), res);
4075+
}
4076+
else
4077+
{
4078+
return Unexpected(Error("All arguments to #concat must be objects"));
4079+
}
40494080
}
40504081
return res;
40514082
}
4052-
else if (range1.isObject() && sep.isObject())
4083+
4084+
// String overload: concatenate all arguments as strings.
4085+
std::string str;
4086+
for (std::size_t i = 0; i < arguments.size() - 1; ++i)
40534087
{
4054-
options = range2;
4055-
range2 = sep;
4056-
return createFrame(range1.getObject(), range2.getObject());
4088+
str += toString(arguments.get(i));
40574089
}
4058-
return range1 + range2;
4090+
return str;
40594091
}
40604092

40614093
std::int64_t
@@ -5107,7 +5139,7 @@ registerStringHelpers(Handlebars& hbs)
51075139
hbs.registerHelper("join", join_fn);
51085140
hbs.registerHelper("implode", join_fn);
51095141

5110-
hbs.registerHelper("concat", dom::makeInvocable(concat_fn));
5142+
hbs.registerHelper("concat", dom::makeVariadicInvocable(concat_fn));
51115143

51125144
static auto strip_fn = dom::makeVariadicInvocable([](
51135145
dom::Array const& arguments)
@@ -6570,7 +6602,7 @@ registerContainerHelpers(Handlebars& hbs)
65706602
return res2;
65716603
}));
65726604

6573-
hbs.registerHelper("concat", dom::makeInvocable(concat_fn));
6605+
hbs.registerHelper("concat", dom::makeVariadicInvocable(concat_fn));
65746606

65756607
static auto flatten_fn = dom::makeInvocable([](dom::Value const& collection, dom::Value const& key) -> dom::Value
65766608
{

0 commit comments

Comments
 (0)