From d8b916e667613af5c293b333c2a075d6fc2bfd5d Mon Sep 17 00:00:00 2001 From: David van Erkelens Date: Thu, 25 Jul 2019 14:16:27 +0200 Subject: [PATCH] number_format modifier (#16) * Create number_format modifier plus a test --- src/builtin/number_format.h | 66 +++++++++++++++++++++++++++++++++++++ src/data.cpp | 2 ++ src/includes.h | 1 + test/modifier.cpp | 19 +++++++++++ 4 files changed, 88 insertions(+) create mode 100644 src/builtin/number_format.h diff --git a/src/builtin/number_format.h b/src/builtin/number_format.h new file mode 100644 index 0000000..58e1361 --- /dev/null +++ b/src/builtin/number_format.h @@ -0,0 +1,66 @@ +/** + * NumberFormat.h + * + * Built-in "|number_format" modifier + * + * @author David van Erkelens + * @copyright 2019 Copernica BV + */ + +/** + * Namespace + */ +namespace SmartTpl { namespace Internal { + +/** + * Class definition + */ +class NumberFormatModifier : public Modifier +{ +public: + /** + * Destructor + */ + virtual ~NumberFormatModifier() {}; + + /** + * Modify a value object + * @param input + * @param params Parameters used for this modification + * @return Value + */ + VariantValue modify(const Value &input, const SmartTpl::Parameters ¶ms) override + { + // Convert input to double + double original(input.toDouble()); + + // make sure we have a parameter containing the format + if (params.size() < 1) throw NoModification(); + + // get the amound of decimals to output + int decimals = params[0].toInteger(); + + // buffer to create the printf format + char format[10]; + + // format the format + sprintf(format, "%%.%if", decimals); + + // calculate size of new string + size_t size = snprintf(nullptr, 0, format, original); + + // create buffer + char buffer[size + 1]; + + // create new string + sprintf(buffer, format, original); + + // create object + return VariantValue(buffer); + } +}; + +/** + * End namespace + */ +}} \ No newline at end of file diff --git a/src/data.cpp b/src/data.cpp index fe54a90..83853d4 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -41,6 +41,7 @@ static Internal::RegexReplaceModifier regex_replace; static Internal::SubStrModifier substr; static Internal::StrPosModifier strpos; static Internal::StrStrModifier strstr; +static Internal::NumberFormatModifier number_format; static Internal::DateFormatModifier date_format; static Internal::UrlencodeModifier urlencode; static Internal::UrldecodeModifier urldecode; @@ -81,6 +82,7 @@ Data::Data() {"substr", &substr}, {"strstr", &strstr}, {"strpos", &strpos}, + {"number_format", &number_format}, {"date_format", &date_format}, {"urlencode", &urlencode}, {"urldecode", &urldecode}, diff --git a/src/includes.h b/src/includes.h index fce4409..9cf5d78 100644 --- a/src/includes.h +++ b/src/includes.h @@ -105,6 +105,7 @@ #include "builtin/substr.h" #include "builtin/strstr.h" #include "builtin/strpos.h" +#include "builtin/number_format.h" #include "builtin/urlencode.h" #include "builtin/urldecode.h" #include "builtin/md5.h" diff --git a/test/modifier.cpp b/test/modifier.cpp index 2ca83c9..3e0eab2 100644 --- a/test/modifier.cpp +++ b/test/modifier.cpp @@ -340,6 +340,25 @@ TEST(Modifier, DateFormat) } } +TEST(Modifier, NumberFormat) +{ + string input("{$var1|number_format}\n{$var1|number_format:0}\n{$var1|number_format:1}\n{$var1|number_format:4}"); + Template tpl((Buffer(input))); + + Data data; + data.assign("var1", "123.45"); + + string expectedOutput("123.45\n123\n123.5\n123.4500"); + + EXPECT_EQ(expectedOutput, tpl.process(data)); + + if (compile(tpl)) // This will compile the Template into a shared library + { + Template library(File(SHARED_LIBRARY)); // Here we load that shared library + EXPECT_EQ(expectedOutput, library.process(data)); + } +} + TEST(Modifier, Count) { string input("{$var|count}");