Skip to content

Commit b320a27

Browse files
matekaflexferrum
authored andcommitted
Batch filter (#150)
1 parent a6d544c commit b320a27

File tree

3 files changed

+71
-3
lines changed

3 files changed

+71
-3
lines changed

src/filters.cpp

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -779,16 +779,61 @@ InternalValue Serialize::Filter(const InternalValue&, RenderContext&)
779779
return InternalValue();
780780
}
781781

782-
Slice::Slice(FilterParams, Slice::Mode)
782+
Slice::Slice(FilterParams params, Slice::Mode mode)
783+
: m_mode{mode}
783784
{
784-
785+
if(m_mode == BatchMode)
786+
{
787+
ParseParams({{"linecount"s, true}, {"fill_with"s, false}}, params);
788+
}
785789
}
786790

787-
InternalValue Slice::Filter(const InternalValue&, RenderContext&)
791+
InternalValue Slice::Filter(const InternalValue& baseVal, RenderContext& context)
788792
{
793+
if(m_mode == BatchMode)
794+
return Batch(baseVal, context);
795+
789796
return InternalValue();
790797
}
791798

799+
InternalValue Slice::Batch(const InternalValue& baseVal, RenderContext& context)
800+
{
801+
auto linecount_value = ConvertToInt(GetArgumentValue("linecount", context));
802+
InternalValue fillWith = GetArgumentValue("fill_with", context);
803+
804+
if(linecount_value <= 0)
805+
return InternalValue();
806+
auto linecount = static_cast<std::size_t>(linecount_value);
807+
808+
bool isConverted = false;
809+
auto list = ConvertToList(baseVal, isConverted);
810+
if (!isConverted)
811+
return InternalValue();
812+
813+
auto elementsCount = list.GetSize().value_or(0);
814+
if(!elementsCount)
815+
return InternalValue();
816+
817+
InternalValueList resultList;
818+
resultList.reserve(linecount);
819+
820+
const auto remainder = elementsCount % linecount;
821+
const auto columns = elementsCount / linecount + (remainder > 0 ? 1 : 0);
822+
for(std::size_t line = 0, idx = 0; line < linecount; ++line)
823+
{
824+
const auto elems = columns - (remainder && line >= remainder ? 1 : 0);
825+
InternalValueList row;
826+
row.reserve(columns);
827+
std::fill_n(std::back_inserter(row), columns, fillWith);
828+
829+
for(std::size_t column = 0; column < elems; ++column)
830+
row[column] = list.GetValueByIndex(idx++);
831+
832+
resultList.push_back(ListAdapter::CreateAdapter(std::move(row)));
833+
}
834+
return ListAdapter::CreateAdapter(std::move(resultList));
835+
}
836+
792837
StringFormat::StringFormat(FilterParams, StringFormat::Mode)
793838
{
794839

src/filters.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ class Slice : public FilterBase
154154
Slice(FilterParams params, Mode mode);
155155

156156
InternalValue Filter(const InternalValue& baseVal, RenderContext& context);
157+
private:
158+
InternalValue Batch(const InternalValue& baseVal, RenderContext& context);
159+
160+
Mode m_mode;
157161
};
158162

159163
class Sort : public FilterBase

test/filters_test.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,3 +489,22 @@ INSTANTIATE_TEST_CASE_P(Escape, FilterGenericTest, ::testing::Values(
489489
InputOutputPair{"'abcd&><efgh' | escape | pprint", "'abcd&amp;&gt;&lt;efgh'"},
490490
InputOutputPair{"'\\\"\\'' | escape | pprint", "'&#34;&#39;'"}
491491
));
492+
493+
INSTANTIATE_TEST_CASE_P(Batch, FilterGenericTest, ::testing::Values(
494+
InputOutputPair{
495+
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] | batch(linecount=3) | pprint",
496+
"[[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, none], [12, 13, 14, 15, 16, none]]"
497+
},
498+
InputOutputPair{
499+
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] | batch(3, 0) | pprint",
500+
"[[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 0], [12, 13, 14, 15, 16, 0]]"
501+
},
502+
InputOutputPair{
503+
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] | batch(3, -1) | pprint",
504+
"[[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, -1]]"
505+
},
506+
InputOutputPair{"[1, 2, 3] | batch(0) | pprint", "none"},
507+
InputOutputPair{"[1, 2, 3, 4] | batch(2) | pprint", "[[1, 2], [3, 4]]"},
508+
InputOutputPair{"'some string' | batch(0) | pprint", "none"},
509+
InputOutputPair{"[] | batch(0) | pprint", "none"}
510+
));

0 commit comments

Comments
 (0)