Review of mustache starts today.

The formal review of the mustache starts today, Sunday the 5th, and ends next week on Tuesday the 14th. The library was developed & submitted by Peter Dimov. Boost.Mustache is an implementation of Mustache templates in C++11. The master branch is frozen during the review and can be found here https://github.com/pdimov/mustache The current documentation can be found here: https://pdimov.github.io/mustache/doc/html/mustache.html Boost.Mustache is an implementation of Mustache templates in C++11. The documentation of Mustache templates is here: https://mustache.github.io/ Review ======== Please explicitly state that you either *accept* or *reject* the inclusion of this library into boost. The accept can be conditional. Also please indicate the time & effort spent on the evaluation and give the reasons for your decision. The review is open to anyone who is prepared to put in the work of evaluating and reviewing the library. Prior experience in contributing to Boost reviews is not a requirement. Some questions to consider: - Does this library bring real benefit to C++ developers for real world use-case? - Do you have an application for this library? - Does the API match with current best practices? - Is the documentation helpful and clear? - Did you try to use it? What problems or surprises did you encounter? - What is your evaluation of the implementation? More information about the Boost Formal Review Process can be found at: http://www.boost.org/community/reviews.html Reviews can also be submitted directly to me. Thank you Peter for submitting yet another boost library & thanks for all the reviews in advance. Building boost.mustache ======================= Here's how to build the library, starting from scratch: 1. Clone Boost from Github: git clone --recurse-submodules https://github.com/boostorg/boost 2. Clone the Mustache library into the Boost tree: cd boost/libs git clone https://github.com/pdimov/mustache cd .. 3. Build b2: ./bootstrap.sh (We assume Linux and g++ from now on. On Windows, it's just `booststrap`.) 4. Generate the header links in the boost/ directory: ./b2 headers 5. Build the Mustache library and its dependencies (e.g. JSON): ./b2 --with-mustache This will place the compiled libraries into the stage/lib directory. It should contain libboost_container.a/.so, libboost_json.a/.so, and liboost_mustache.a/.so. You can now build and run the Mustache examples by using e.g. g++ libs/mustache/example/html.cpp -o html -I . -L stage/lib -lboost_mustache -lboost_json ./html

On Sat, Feb 4, 2023 at 7:56 PM Klemens Morgenstern via Boost <boost@lists.boost.org> wrote:
Boost.Mustache is an implementation of Mustache templates in C++11.
I cloned this bad boy into ${BOOST}/libs and then tried to build a Visual Studio Solution for it with: $ cmake -G "Visual Studio 16 2019" -A x64 -B bin64 Unfortunately this failed, and I got a bunch of errors like this: CMake Error at CMakeLists.txt:10 (add_library): Target "boost_mustache" links to target "Boost::config" but the target was not found. Perhaps a find_package() call is missing for an IMPORTED target, or an ALIAS target is missing? Then I was advised by the author to use this command line from the root: cmake -G "Visual Studio 16 2019" -A x64 -B libs/mustache/bin64 -DBOOST_INCLUDE_LIBRARIES=mustache -DBUILD_TESTING=ON This also produced an error: CMake Error: The source "C:/Users/vinnie/src/boost/CMakeLists.txt" does not match the source "C:/Users/vinnie/src/boost/libs/mustache/CMakeLists.txt" used to generate cache. Re-run cmake with a different source directory. Tried adding the path to the lib: cmake -G "Visual Studio 16 2019" -A x64 -B libs/mustache/bin64 -DBOOST_INCLUDE_LIBRARIES=mustache -DBUILD_TESTING=ON libs/mustache Same result. Well I deleted all the cached artifacts and then used this line cmake -G "Visual Studio 16 2019" -A x64 -B bin.v2/vs/mustache -DBOOST_INCLUDE_LIBRARIES=mustache -DBUILD_TESTING=ON libs/mustache Finally I got a Visual Studio solution with some projects in it (see attached image). It builds but the solution and projects have some cosmetic issues: * Every solution built from the root has the same name Boost.sln * Every Visual Studio window that opens Boost.sln has the title "Boost" (can't tell which is which) * mustache .vcxproj files have unnecessary nesting. "Header Files" folder then "boost" then "mustache". * dependencies are thrown together with the library-specific projects It works, but does not bring me joy. Thanks

Hi to everyone. Sorry, I'm a lurker of the mailing list and I almost never reply, but I've a question. Mustache is a library that needs at least C++11, while in another thread (Dropping C++03 support again) you're talking about dropping the support for C++03. But it means that now it's supported, so this library does not satisfy the requirement to be usable by C++03 compilers. What do you do in this case? The C++03 support is needed only for existing libraries or also for new ones? I'm asking because I've some idea for libraries and I'd like to propose one of them someday, but I need to know if they can satisfy the compiler requirements (I usually work only with modern compilers). What do you do with compiler support in this case? Daniele Lupo -----Messaggio originale----- Da: Boost <boost-bounces@lists.boost.org> Per conto di Klemens Morgenstern via Boost Inviato: domenica 5 febbraio 2023 04:56 A: boost@lists.boost.org Cc: Klemens Morgenstern <klemensdavidmorgenstern@gmail.com> Oggetto: [boost] Review of mustache starts today. The formal review of the mustache starts today, Sunday the 5th, and ends next week on Tuesday the 14th. The library was developed & submitted by Peter Dimov. Boost.Mustache is an implementation of Mustache templates in C++11. The master branch is frozen during the review and can be found here https://github.com/pdimov/mustache The current documentation can be found here: https://pdimov.github.io/mustache/doc/html/mustache.html Boost.Mustache is an implementation of Mustache templates in C++11. The documentation of Mustache templates is here: https://mustache.github.io/ Review ======== Please explicitly state that you either *accept* or *reject* the inclusion of this library into boost. The accept can be conditional. Also please indicate the time & effort spent on the evaluation and give the reasons for your decision. The review is open to anyone who is prepared to put in the work of evaluating and reviewing the library. Prior experience in contributing to Boost reviews is not a requirement. Some questions to consider: - Does this library bring real benefit to C++ developers for real world use-case? - Do you have an application for this library? - Does the API match with current best practices? - Is the documentation helpful and clear? - Did you try to use it? What problems or surprises did you encounter? - What is your evaluation of the implementation? More information about the Boost Formal Review Process can be found at: http://www.boost.org/community/reviews.html Reviews can also be submitted directly to me. Thank you Peter for submitting yet another boost library & thanks for all the reviews in advance. Building boost.mustache ======================= Here's how to build the library, starting from scratch: 1. Clone Boost from Github: git clone --recurse-submodules https://github.com/boostorg/boost 2. Clone the Mustache library into the Boost tree: cd boost/libs git clone https://github.com/pdimov/mustache cd .. 3. Build b2: ./bootstrap.sh (We assume Linux and g++ from now on. On Windows, it's just `booststrap`.) 4. Generate the header links in the boost/ directory: ./b2 headers 5. Build the Mustache library and its dependencies (e.g. JSON): ./b2 --with-mustache This will place the compiled libraries into the stage/lib directory. It should contain libboost_container.a/.so, libboost_json.a/.so, and liboost_mustache.a/.so. You can now build and run the Mustache examples by using e.g. g++ libs/mustache/example/html.cpp -o html -I . -L stage/lib -lboost_mustache -lboost_json ./html _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Sun, Feb 5, 2023 at 6:07 PM jepessen wrote:
Mustache is a library that needs at least C++11, while in another thread (Dropping C++03 support again) you're talking about dropping the support for C++03. But it means that now it's supported, so this library does not satisfy the requirement to be usable by C++03 compilers. What do you do in this case? The C++03 support is needed only for existing libraries or also for new ones? I'm asking because I've some idea for libraries and I'd like to propose one of them someday, but I need to know if they can satisfy the compiler requirements (I usually work only with modern compilers).
What do you do with compiler support in this case?
Not all Boost libraries support C++03. Some support only C++11 and above, others support only C++14 and above. The only requirement for new libraries being proposed to Boost is that they compile with the latest C++ standard and at least 2 C++ compiler implementations. The thread you're seeing is about those Boost libraries that still support C++03 that feel they cannot drop it because other Boost libraries depend on them. Even now, any Boost library that has no other Boost library depending on it, is free to drop support for all C++ standard versions below the latest (C++20). i.e. Boost library authors have always had this freedom. Glen

On Mon, 6 Feb 2023 at 00:11, Glen Fernandes via Boost <boost@lists.boost.org> wrote:
The only requirement for new libraries being proposed to Boost is that they compile with the latest C++ standard and at least 2 C++ compiler implementations.
This needs to go to the requirements page https://github.com/boostorg/website/pull/728 Best regards, -- Mateusz Loskot, http://mateusz.loskot.net

On Sun, Feb 5, 2023 at 6:33 PM Mateusz Loskot wrote:
On Mon, 6 Feb 2023 at 00:11, Glen Fernandes wrote:
The only requirement for new libraries being proposed to Boost is that
they
compile with the latest C++ standard and at least 2 C++ compiler implementations.
This needs to go to the requirements page https://github.com/boostorg/website/pull/728
Absolutely (thanks). Glen

Ok thanks for your reply, this is interesting. Regards Daniele Lupo From: Glen Fernandes <glen.fernandes@gmail.com> Sent: Monday, February 6, 2023 12:11 AM To: boost@lists.boost.org Cc: jepessen@wteam.it Subject: Re: [boost] R: Review of mustache starts today. Not all Boost libraries support C++03. Some support only C++11 and above, others support only C++14 and above [cut]

What is the relationship, if any, between Mustache and Boostash from a library in a week episode at C++Now from some years ago? Robert Ramey

Robert Ramey wrote:
What is the relationship, if any, between Mustache and Boostash from a library in a week episode at C++Now from some years ago?
None, apart from them both being implementations of the same templating language, http://mustache.github.io/.

On 5/02/2023 16:55, Klemens Morgenstern wrote:
The current documentation can be found here: https://pdimov.github.io/mustache/doc/html/mustache.html
Boost.Mustache is an implementation of Mustache templates in C++11.
The documentation of Mustache templates is here: https://mustache.github.io/
At a glance, it seems unfortunate that lambdas are currently unsupported (even though they're listed as optional, so their omission is not grounds for rejection). I do wonder if attempting to add them might alter some design decisions, though, such as how partials are submitted -- a lambda might want to use a combination of partials from its parent context as well as "private" partials, for example.

On 7/02/2023 13:06, Vinnie Falco wrote:
it seems unfortunate that lambdas are currently unsupported
What are "lambdas" in this context, do you have a link I can read?
From the Mustache spec, see the "Lambdas" section of <http://mustache.github.io/mustache.5.html> Or more fundamentally: <https://github.com/mustache/spec/blob/master/specs/~lambdas.yml> Relatedly, the docs don't really give any comparison to other existing libraries either; for example the current "official" C++ implementation of Mustache appears to be <https://github.com/no1msd/mstch>. At a glance, this appears to have more features, but uses a non-Boost.Json input type. I have not attempted to use either library.

This looks strange without an api that allows returning by value. As-is, everything seems to assume the user wants to mutate their values by reference. Mutating by reference is fine, but at least exposing an api that allows another style seems important. WL
On Feb 6, 2023, at 7:14 PM, Gavin Lambert via Boost <boost@lists.boost.org> wrote:
On 7/02/2023 13:06, Vinnie Falco wrote:
it seems unfortunate that lambdas are currently unsupported What are "lambdas" in this context, do you have a link I can read?
From the Mustache spec, see the "Lambdas" section of <http://mustache.github.io/mustache.5.html>
Or more fundamentally: <https://github.com/mustache/spec/blob/master/specs/~lambdas.yml>
Relatedly, the docs don't really give any comparison to other existing libraries either; for example the current "official" C++ implementation of Mustache appears to be <https://github.com/no1msd/mstch>. At a glance, this appears to have more features, but uses a non-Boost.Json input type.
I have not attempted to use either library.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 7/02/2023 13:23, William Linkmeyer wrote:
This looks strange without an api that allows returning by value. As-is, everything seems to assume the user wants to mutate their values by reference.
Mutating by reference is fine, but at least exposing an api that allows another style seems important.
This might have been better if you'd replied to and quoted a different message; I don't think it's related to my thread at all. (Also, don't top-post, which probably contributed to using the wrong context.) I assume you're referring to proposed Boost.Mustache's output_ref?

On Sat, Feb 4, 2023 at 9:56 PM Klemens Morgenstern via Boost <boost@lists.boost.org> wrote:
The formal review of the mustache starts today, Sunday the 5th, and ends next week on Tuesday the 14th.
While I would like to do a review of this library I'm not going to have the time within that time frame. As I'm double booked with work and the WG21 meeting. Can the review be extended to the end of next week? -- -- René Ferdinand Rivera Morell -- Don't Assume Anything -- No Supone Nada -- Robot Dreams - http://robot-dreams.net

One question I have: How is boost.mustache different than https://github.com/no1msd/mstch ? What is gained by re-inventing the wheel? Robert Ramey

On Mon, Feb 6, 2023 at 7:27 PM Robert Ramey via Boost <boost@lists.boost.org> wrote:
How is boost.mustache different than https://github.com/no1msd/mstch ?
Robert just out of curiosity, when was the last commit to that repository? Thanks

Robert Ramey wrote:
One question I have:
How is boost.mustache different than https://github.com/no1msd/mstch ?
The main difference is that the proposed Boost.Mustache uses Boost.JSON for the input data, instead of rolling its own json::value. (This is not a critique of no1msd/mstch, which predates Boost.JSON and could not have used it.) (Boost.Mustache also uses Boost.JSON's storage_ptr for all its allocations.) In addition, it uses Boost.Describe to support C++ objects directly, instead of some bespoke mechanism. One downside is that boost::json::value can't hold a lambda, so lambdas are not supported. There are probably other differences as well; Boost.Mustache can take its template input in chunks, not all at once; it also passes the official Mustache test suite, which requires getting whitespace "just right", a surprisingly nontrivial undertaking. I'm not sure how no1msd/mstch fares on these criteria, as I haven't really tried it, only read the README.

Le 2023-02-07 04:44, Peter Dimov via Boost a écrit :
In addition, it uses Boost.Describe to support C++ objects directly, instead of some bespoke mechanism.
One downside is that boost::json::value can't hold a lambda, so lambdas are not supported.
This raises another question. My current understanding is that the current process is: C++Object ---> Json representation (via describe) ---> Mustache rendering This means the mandatory creation of a json object. Is it only because json support as an input source is mandatory, and once you got it it is much simpler to use it, or are there other reasons which prevent doing the following: C++Object ---> Mustache rendering (via describe) Regards, Julien

Julien Blanc wrote:
Le 2023-02-07 04:44, Peter Dimov via Boost a écrit :
In addition, it uses Boost.Describe to support C++ objects directly, instead of some bespoke mechanism.
One downside is that boost::json::value can't hold a lambda, so lambdas are not supported.
This raises another question. My current understanding is that the current process is:
C++Object ---> Json representation (via describe) ---> Mustache rendering
This means the mandatory creation of a json object. Is it only because json support as an input source is mandatory, and once you got it it is much simpler to use it, or are there other reasons which prevent doing the following:
C++Object ---> Mustache rendering (via describe)
As-is, this would require the library to be templated with everything in the header. We've been thinking about a type `json::value_view` that is to `json::value` what `string_view` is to `string` - a way to get a "reference" to a type supported natively by `value_from` that looks like a `json::value` without having to create a `json::value` temporary and copy everything. We don't have agreement yet whether this type will be added to Boost.JSON. If not, I'll need to implement it in Mustache.

On Tue, Feb 7, 2023 at 5:50 AM Peter Dimov via Boost <boost@lists.boost.org> wrote:
We've been thinking about a type `json::value_view` that is to `json::value` what `string_view` is to `string` - a way to get a "reference" to a type supported natively by `value_from` that looks like a `json::value` without having to create a `json::value` temporary and copy everything.
On record, I am not terribly fond of this solution. Peter managed to convince me of the importance of a solution but I am not sure that it should be a JSON thing. Boost.JSON is designed for maximum compatibility with Node.js and other non-C++ languages. It is designed for fast serialization and parsing using the json::value variant type. It is not designed for the use-cases contemplated by the aforementioned value_view. Instead I would prefer a more general type-erasing facility which can be used on user-defined types. The facility would need a variant-like type (the replacement for boost::json::value) that can capture any C++ builtin type at full fidelity (which Boost.JSON cannot do, and was not designed to do). For example it should capture 128 bit integers, or floats, or shorts, as their native type. This facility could provide type traits to detect things such as is_optional_like, is_contiguous_array_of, is_key_value_map and so forth. And there could be the necessary wrappers to type-erase these concept-driven things. There is a working prototype of the json::value_view described above but it has limitations. It only works for certain kinds of iterators (those that can be type-erased without allocating memory). And other things. I believe there is room in Boost.Describe for this facility (or, perhaps another library, but Describe is a logical place for several reasons). Thanks

A couple of questions for Peter:
How is boost.mustache different than https://github.com/no1msd/mstch ?
1. If we get the library into Boost, is it an option to get it listed in https://mustache.github.io/? 2. Does Mustache make any assumptions on encoding? From the code I'd say UTF8 but I can't find anything in the spec. Thanks, Ruben.

Ruben Perez wrote:
A couple of questions for Peter:
How is boost.mustache different than https://github.com/no1msd/mstch ?
1. If we get the library into Boost, is it an option to get it listed in https://mustache.github.io/?
I don't know; we can certainly try.
2. Does Mustache make any assumptions on encoding? From the code I'd say UTF8 but I can't find anything in the spec.
I can't find anything about encoding in the Mustache specs either, but UTF-8 sounds like the right thing.

The formal review of the mustache starts today, Sunday the 5th, and ends next week on Tuesday the 14th.
The library was developed & submitted by Peter Dimov.
Boost.Mustache is an implementation of Mustache templates in C++11.
The master branch is frozen during the review and can be found here https://github.com/pdimov/mustache
The current documentation can be found here: https://pdimov.github.io/mustache/doc/html/mustache.html
Boost.Mustache is an implementation of Mustache templates in C++11.
The documentation of Mustache templates is here: https://mustache.github.io/ I have some serious reservations about Mustache as a text templating language, and some even more serious reservations about the minimal (no extensions) version of Mustache used by the proposed library. In
On 05.02.23 04:55, Klemens Morgenstern via Boost wrote: particular, the lack of the lambda extension severely hurts the versatility of this library, and because boost::json::value is used as the basic vocabulary type, there is no good way to add this extension to the library. Reservation 1: The plural problem --------------------------------- One fundamental applications of a text templating language is to format a user-visible text string with values substituted in, like the following: "Found %d files and %d directories." Now, one problem with the above is that it uses the plural forms "files" and "directories" even if the number is 1, which is grammatically incorrect. I can kind of work around this by using text like this: "Found %d file(s) and %d directorie(s)." But that's ugly, it doesn't work for irregular plurals, and it definitely doesn't work for languages like Arabic where almost all plurals are irregular and there is a dual form in addition to the singular and the plural. The Jinja templating language solves this problem with conditionals: "Found {{num_files}} {% if num_files == 1 %}file{% else %}files{% endif %} and {{num_dirs}} {% if num_dirs == 1 %}directory{% else %}directories{% endif %}" That's ugly, but it solves the problem at the templating level. It can be made prettier by using macros, but it's good enough to demonstrate that the problem can be solved Can this problem be solved effectively at a different level? Maybe, but the alternative is likely to be even uglier. Three alternate solutions come to mind, none of them good. The first is to just prepare multiple versions of the text string: "Found {{num_files}} files and {{num_dirs}} directories." "Found 1 file and {{num_dirs}} directories." "Found {{num_files}} files and 1 directory." "Found 1 file and 1 directory." This obviously does not scale, as it requires n**m different strings, where n is the number of grammatical numbers in the language (2 for English) and m is the number of variables being substituted. Another possibility is to pass in the words being pluralized as arguments: "Found {{num_files}} {{files_word}} and {{num_dirs}} {{dirs_word}}." This works in this simple case for English, but it breaks down when more complex grammatical structures are used, e.g. "1 files *has* been found" vs "2 files *have* been found". It also pushes the hard work into the calling code, which is less than ideal, especially if it means that the calling code now has to contain language-specific code. A third possibility, specifically when generating HTML code, is to generate Javascript to perform the pluralization on the client side. This is too complicated to demonstrate in a quick example, only works if the result is HTML (or something equivalently powerful), and only works if Javascript is enabled. Is it possible to solve this problem with the lambda extension? Kind of. The lambda extension would allow templates like the following: "Found {{num_files}} {{#choose_plural}}num_files|file|files{{/choose_plural}} and {{num_dirs}}{{#choose_plural}}num_dirs|directory|directories{{/choose_plural}}." However, this puts the onus on the 'choose_plural' function to parse the section string, look up the controlling variable, and use the result to choose the correct string. This means that the choose_plural function ends up duplicating a lot of the functionality of the library. It's a big ugly hack, but it's a big ugly hack that works, which beats not having any solution at all. Reservation 2: The trailing comma problem ----------------------------------------- Mustache sections can be used to list array elements in text. This is one of the primary advantages of using a full templating system like Mustache over something like boost::format or std::format. However, it does not allow a separator between the elements of the array. I can list the elements without separator: "Found these files: {{#files}}{{.}}{{/files}}." However, if I try to add a separator, I also get a trailing separator at the end: "Found these files: {{#files}}{{.}}, {{/files}}and nothing else." This is annoyance for human-readable text. It becomes more than an annoyance when generating machine-readable text. This makes the proposed library unsuitable for generating, for example, program code or json. Jinja solves this problem with a built-in filter: "Found these files: {{files|join(', ')}}." Is it possible to solve this problem with the lambda extension? Again, kind of. I could define a function that allows this: "Found these files: {{#join}}files|, {{/join}}." However, the function would again have to parse the section string, extract the variable name, look up the variable, and use that to generate the string. It's ugly an hack that works, which still beats not having any solution at all. Conclusion ---------- I don't think Mustache is a very good templating language. With the lambda extension, there are ways to hack around its inadequacies. Without the lambda extension, it feels too restrictive to be useful. Since a C++ implementation that supports the lambda extension already exists in the form of the mstch library, do we really want the more restrictive proposed library in Boost? On the other hand, the lambda extension is also fairly limited, and does not provide a clean solution to either of the above problems. What is really needed is something that goes beyond the lambda extension by allowing arbitrary expressions to be evaluated and passed to the function, like this: "Found {{num_files}} {{pluralize(num_files, 'file, 'files'}} and {{num_dirs}} {{pluralize(num_dirs, 'directory', 'directories')}}." "Found these files: {{join(files, ', ')}}. I would love to be convinced that the proposed library is more useful than it looks at first glance. Maybe there is a non-obvious way to use the built-in functionality of Mustache to provide the desired results, analogous to the way C++ template metaprogramming extended the expressive power of C++ templates. However, if I am not convinced then I expect to vote against its acceptance into Boost. -- Rainer Deyke (rainerd@eldwood.com)

On Tue, Feb 7, 2023 at 7:29 AM Rainer Deyke via Boost <boost@lists.boost.org> wrote:
Reservation 1: The plural problem ---------------------------------
One fundamental applications of a text templating language is to format a user-visible text string with values substituted in, like the following:
"Found %d files and %d directories."
[snip] The way that I'm familiar with to solve such problems in general is to properly localize your strings. Localization is not just for language but for gender and plurality. And the usual way to do localization is to provide whole alternate strings for the messages. Which is something that would happen outside of the template itself. As it would mean reading from a database of alternate strings. -- -- René Ferdinand Rivera Morell -- Don't Assume Anything -- No Supone Nada -- Robot Dreams - http://robot-dreams.net

On 07.02.23 15:28, René Ferdinand Rivera Morell via Boost wrote:
On Tue, Feb 7, 2023 at 7:29 AM Rainer Deyke via Boost <boost@lists.boost.org> wrote:
Reservation 1: The plural problem ---------------------------------
One fundamental applications of a text templating language is to format a user-visible text string with values substituted in, like the following:
"Found %d files and %d directories."
[snip]
The way that I'm familiar with to solve such problems in general is to properly localize your strings. Localization is not just for language but for gender and plurality. And the usual way to do localization is to provide whole alternate strings for the messages. Which is something that would happen outside of the template itself. As it would mean reading from a database of alternate strings.
If you read my full post, you will see that I have explicitly addressed and rejected that option. The problem is that it doesn't scale. In the above example, I would need four possibilities for English: "Found %d files and %d directories." "Found 1 file and %d directories." "Found %d files and 1 directory." "Found 1 file and 1 directory." Each additional variable doubles the number of strings I need, so at eight variables I am up to 256 strings, at which point I would definitely write a script to generate the strings. And that's just for English. Arabic has a total of 6 forms I might use, so for 8 variables I need 1679616 different strings. I don't even want to keep that many strings in RAM, let alone write them by hand. -- Rainer Deyke (rainerd@eldwood.com)

Rainer Deyke wrote:
I would love to be convinced that the proposed library is more useful than it looks at first glance. Maybe there is a non-obvious way to use the built-in functionality of Mustache to provide the desired results, analogous to the way C++ template metaprogramming extended the expressive power of C++ templates. However, if I am not convinced then I expect to vote against its acceptance into Boost.
I agree with your analysis of Mustache's deficiencies, and I don't have a good answer at this time. We will need to address this one way or the other, but I can't promise how long this will take. It's very easy to quickly add ad-hoc nonstandard extensions to Mustache to take care of the issues, but I don't want to do that. Some thought will be required.

On 07.02.23 14:29, Rainer Deyke via Boost wrote:
Reservation 1: The plural problem Reservation 2: The trailing comma problem
So after writing that long wall of text, I came up with a solution that works in plain Mustache. I simply need to pass all my json through an annotation function. This function modifies the incoming json as follows: - Any integer is replaced by a json object like this: { "value": value, "is_one": value == 1, "is_two": value == 2, "is_zero": value == 0, // more annotations as needed } - Any array is replaced with an array of json objects as follows: [ { "value": org_array[0], "index": 0, "is_first": true, "is_last": false }, { "value": org_array[1], "index": 1, "is_first": false, "is_last": false }, // ... { "value": org_array[size - 1], "index": size - 1, "is_first": false, "is_last": true } ] This allows the following mustache templates: "Found {{#num_files}}{{value}} {{#is_one}}file{{/is_one}}{{^is_one}}files{{/is_one}}{{/num_files}} and {{#num_dirs}} {{#is_one}}directory{{/is_one}}{{^is_one}}directories{{/is_one}}{{/num_dirs}}." "Found these files:{{#files}}{{value}}{{^is_last}}, {{/is_last}}{{/files}}." I wouldn't call this solution nice - there's a significant performance cost involved - but I can live with it. I actually like this solution better than any hack I could come up with using the lambda extension, since it correctly works in nested contexts. I no longer consider the lack of lambda extension support a valid reason for not accepting this library into Boost. -- Rainer Deyke (rainerd@eldwood.com)

On Sat, Feb 4, 2023 at 7:56 PM Klemens Morgenstern via Boost <boost@lists.boost.org> wrote:
Please explicitly state that you either *accept* or *reject* the inclusion of this library into boost.
I am deeply appreciative of the years I have spent working with the author on the C++ language Slack (at https://slack.cpp.al/) and the benefits this has brought to my libraries. However, I must REJECT this library.
Also please indicate the time & effort spent on the evaluation and give the reasons for your decision.
I spent quite a lot of time. 20% of it was wrestling with the cmake scripts. 40% was wrestling with authoring a boost::buffers::source, which came out terribly: <https://github.com/vinniefalco/http_io/blob/abb722981d1adfc37524abed87c8bb88720ac9ec/example/server/mustache_source.hpp#L28> And the other 40% was figuring out what and how to write this review, which I will try to keep brief. "What makes a good Boost library candidate?" I believe that when a library is accepted into Boost, it has to walk on water. That means it can't just work, it has to work well and it needs to have some unique qualities which distinguish it from all other libraries in its class. For example here are some of the reasons that my libraries and other libraries are a cut above: Boost.Beast: First HTTP/Websocket library using idiomatic Asio Boost.JSON: The only streaming parser/serializer for JSON with performant DOM Boost.URL: Superior interface (class url_view) and manipulation capability (class url) Boost.Aedis: Beautiful multiplexing of concurrent requests and responses onto a single socket Boost.Describe: C++14 Reflection today, instead of 20 years from now. Unfortunately Boost.Mustache does not distinguish itself by demonstrating excellence. If there is a subsequent re-review, I would like to see: * Better documentation on what Mustache is, for people who don't know - The author has already acknowledged this on the list * Better documentation for public APIs - The meaning of each parameter, in clear terms - How to pass nothing for T2 in render and renderer + or better yet, a way to omit T2 entirely - Examples of correct syntax and usage for each function * Explanation and example code for specific use-cases: - Streaming the template from a file incrementally - Using native Boost.JSON objects in T1 and T2 * Implement the output streaming interface described here: - <https://github.com/pdimov/mustache/issues/2> * Better APIs than what is on offer: - A way to transfer ownership of JSON objects into the renderer without copying, e.g. renderer::renderer( json::object&& data, json::object&& partials ) noexcept; - A way to use user-defined types for T1 and T2 which do not require constructing a json::value + but capturing native types with full fidelity, instead of using JSON as a crutch for thorough type-erasure (i.e. not json::value_view). - Exploration or full implementation of lambdas - Exploration of on-demand partials as described here: + https://github.com/pdimov/mustache/issues/1 * HTML escaping support (maybe its already there?) + <https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-in-html> * I need to be able to write a great buffers::source implementation for Boost.Mustache. "Exploration" above means either a full implementation at Boost quality, or some kind of report of the results of experimentation indicating how the feature might be implemented in a future version or why the feature is not practical or a good match for C++. I know that "pretty" Visual Studio solutions are not a requirement, and that I'm an outlier in terms of using the IDE exclusively, but if the CMLs could at least organize the source files and have some kind of lib-as-root setting that would be a really great "plus" and a way for Boost to distinguish itself as walking on water instead of just providing the minimum "working" build scripts.
- Does this library bring real benefit to C++ developers for real world use-case? - Do you have an application for this library?
Yes I think templating is a great fit for Boost now that we have these other network component. The Mustache spec seems as good as anything else.
- Is the documentation helpful and clear?
It is the bare minimum and it doesn't do the library any favors. Someone who is new to Mustache and of average C++ skill is going to have a challenging experience with the documentation in its current state.
...
Thank you very much Peter for putting this together, I hope that this review will be seen constructively and I very much hope to review or use a better version of this library soon. Thanks

[off-list reply] In article <CA+EzHGfsNb86wi17zbX=RSA=sH2OJguLE_AacKmMTgGNbLfj4A@mail.gmail.com>, Vinnie Falco via Boost <boost@lists.boost.org> writes:
I know that "pretty" Visual Studio solutions are not a requirement, and that I'm an outlier in terms of using the IDE exclusively, [...]
Honestly, I don't think you're an outlier; it's just that many boost authors/contributors are unix dudes historically. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://ComputerGraphicsMuseum.org> Legalize Adulthood! (my blog) <http://LegalizeAdulthood.wordpress.com>

I wanted to raise a concern on allocations before emitting my review. I've gone ahead and modified the html.cpp example to install a "spying" memory_resource as a quick and dirty way of visualizing allocations. I've refactored the code to something like this: // Let's call this the "init" section boost::json::value vars = boost::json::value_from(ref, spy_ptr); boost::json::value partials ( { { "header", header }, { "footer", footer }, { "item", item }, { "body", body } }, spy_ptr ); // "renderer_ctor" section boost::mustache::renderer rd (std::move(vars), std::move(partials), spy_ptr); // "parsing" section rd.render_some( html, dummy ); rd.finish( dummy ); This yielded the following results on allocations: section | total bytes | total allocations ------------------------------------------------- init | 1550 | 31 renderer_ctor | 1582 | 32 parsing | 1900 | 39 I was surprised by the number of allocations that the actual parsing does. Is this because renderer::render_some must assume that the input buffer may not outlive the actual parsing? If I am not mistaken, renderer_ctor's allocations happen because value_from is invoked unconditionally, even if a json::value&& is passed in, which yields in a copy. My other point to note is about HTML escaping. I want to note this point as a reference for other reviewers, as the author is already aware of this. Some special characters should be HTML encoded, additionally to the ones that are being escaped today. I've reviewed other Mustache libraries looking for how did they handle this topic and whether they had any known vulnerability. The most active one seems the JavaScript one (https://github.com/janl/mustache.js). Looking into the Synk vulnerability database, I've found https://security.snyk.io/vuln/npm:mustache:20151207 (CVE-2015-8862), which leads to XSS exploits and does affect Boost.Mustache, too. Two exploits are possible: * The backtick character seems to have special meaning in ancient versions of IE (https://html5sec.org/#59, https://github.com/janl/mustache.js/pull/388) * When using HTML unquoted attributes (e.g. <a href={{user_data}}>), escaping the equal sign can mitigate the risk of attribute injection. (IMHO attributes without quotes make kittens die, but this is listed as a vulnerability). The JavaScript library performs this replacement: * Backtick is replaced by ` * Equal sign is replaced by = They also escape the forward slash (#x2f;). I haven't found a vulnerability to point you too, but I guess that could be added as additional hardening, if you like. Many thanks, Ruben.

On Wed, Feb 8, 2023 at 11:12 AM Ruben Perez via Boost <boost@lists.boost.org> wrote:
My other point to note is about HTML escaping.
There are 4 use-cases IMHO, for a templating engine: 1) pure text-template. No escaping; 2) text-template to embed in some custom format, with its own escaping rules; 3) template generates HTML, and "some" characters of the placeholders need escaping; 4) template generates text, possibly HTML-like, meant to be embedded into HTML, thus "more" escaping is necessary. #3 use regular mustaches, {{foo}}, while #4 uses "thick" ones, {{{foo}}}. These are the regular uses Mustache was created for. But should we forego #1 and #2 completely? Why not make the escaping pluggeable, to have something more flexible? (and that flexible escaping would still be made aware of {{foo}} vs {{{foo}}} to decide for itself whether to escape the same or not). Go has two packages for templating, text/template [1] and html/template, but they are the same template engine AFAIK, it's just the escaping rules that change I believe. Sounds to like Boost.Mustache should not be HTML-only. My $0.02. --DD [1]: https://pkg.go.dev/text/template

Le mercredi 08 février 2023 à 11:44 +0100, Dominique Devienne via Boost a écrit :
On Wed, Feb 8, 2023 at 11:12 AM Ruben Perez via Boost <boost@lists.boost.org> wrote:
There are 4 use-cases IMHO, for a templating engine: 1) pure text-template. No escaping; 2) text-template to embed in some custom format, with its own escaping rules; 3) template generates HTML, and "some" characters of the placeholders need escaping; 4) template generates text, possibly HTML-like, meant to be embedded into HTML, thus "more" escaping is necessary.
#3 use regular mustaches, {{foo}}, while #4 uses "thick" ones, {{{foo}}}.
I did not check what boost.mustache does, but from the documentation ( https://mustache.github.io/mustache.5.html ): “All variables are HTML escaped by default. If you want to return unescaped HTML, use the triple mustache: {{{name}}}.”. I understand “unescaped HTML” as “plain text”. So thick mustaches {{{foo}}} would be #1. If that's not the case (ie it can't produce plain text), that would make boost.mustache completely useless for me. Regards, Julien

On Wed, Feb 8, 2023 at 1:32 PM Julien Blanc <julien.blanc@tgcm.eu> wrote:
Le mercredi 08 février 2023 à 11:44 +0100, Dominique Devienne via Boost
On Wed, Feb 8, 2023 at 11:12 AM Ruben Perez via Boost <boost@lists.boost.org> There are 4 use-cases IMHO, for a templating engine: 1) pure text-template. No escaping; 2) text-template to embed in some custom format 3) template generates HTML 4) template generates text, possibly HTML-like
I did not check what boost.mustache does, but from the documentation ( https://mustache.github.io/mustache.5.html ): “All variables are HTML escaped by default. If you want to return unescaped HTML, use the triple mustache: {{{name}}}.”. I understand “unescaped HTML” as “plain text”. So thick mustaches {{{foo}}} would be #1.
If that's not the case (ie it can't produce plain text), that would make boost.mustache completely useless for me.
I think you're right, and I got it wrong above. If foo contains the text "<foo&bar/>" (w/o the dquotes), then the template {{foo}} should expand to ">foo&bar/<", while {{{foo}}} should expand to "<foo&bar/>" verbatim. So that covers #4 (and there's no #3...), and #1, respectively. But that leaves #2 uncovered I think. So I still think escaping should be an independent / orthogonal dimension from the templating proper.

Dominique Devienne wrote:
There are 4 use-cases IMHO, for a templating engine: 1) pure text-template. No escaping; 2) text-template to embed in some custom format, with its own escaping rules; 3) template generates HTML, and "some" characters of the placeholders need escaping; 4) template generates text, possibly HTML-like, meant to be embedded into HTML, thus "more" escaping is necessary.
I actually encountered (2) when writing the examples, because to generate proper markdown, apostrophes must be escaped. So there's definitely a practical need to supply a custom escaping function.

Ruben Perez wrote:
This yielded the following results on allocations:
section | total bytes | total allocations ------------------------------------------------- init | 1550 | 31 renderer_ctor | 1582 | 32 parsing | 1900 | 39
I was surprised by the number of allocations that the actual parsing does. Is this because renderer::render_some must assume that the input buffer may not outlive the actual parsing?
I haven't optimized for number of allocations, my focus was on correctness. In this specific case I would guess these are due to the temporary saving and restoring the delimiters on each partial invocation. Since json::string doesn't use SBO to keep sizeof small, these go to the allocator. To avoid this I'll need to write my own string or maybe switch to std::pmr::string except using my own polymorphic_allocator.

On Wed, Feb 8, 2023 at 9:23 AM Peter Dimov via Boost <boost@lists.boost.org> wrote:
Since json::string doesn't use SBO to keep sizeof small
Yes it do ! Thanks -- Regards, Vinnie Follow me on GitHub: https://github.com/vinniefalco

Vinnie Falco wrote:
On Wed, Feb 8, 2023 at 9:23 AM Peter Dimov via Boost <boost@lists.boost.org> wrote:
Since json::string doesn't use SBO to keep sizeof small
Yes it do !
Should be something else, then, because the delimiters are two characters long so should fit. May be the section name stack, or the section text.

On Wed, Feb 8, 2023 at 9:48 AM Peter Dimov via Boost <boost@lists.boost.org> wrote:
Yes it do !
10 or 14 bytes depending on architecture: <https://github.com/boostorg/json/blob/22c1b391d4fe8b35a5c5637f8677d6d619a25e6e/include/boost/json/detail/string_impl.hpp#L38> Thanks

On 08/02/2023 19:46, Vinnie Falco via Boost wrote:
On Wed, Feb 8, 2023 at 9:48 AM Peter Dimov via Boost <boost@lists.boost.org> wrote:
Yes it do !
10 or 14 bytes depending on architecture:
For 64 bits machines some string implementations (like boost::container::string) can give you 23 bytes (22 character plus '\0'. In 32 bit mode it should be roughly 10 characters plus '\0'. I don't know if that can make any difference, though. Ion

Should be something else, then, because the delimiters are two characters long so should fit.
From my debugging, seems to be copying json::value's into the context stack (renderer.cpp:1093, renderer.cpp:1103). Is all this copying preventable with the current interface? Or would it be with the json::value_view thing?
Regards, Ruben.

Ruben Perez wrote:
Should be something else, then, because the delimiters are two characters long so should fit.
From my debugging, seems to be copying json::value's into the context stack (renderer.cpp:1093, renderer.cpp:1103). Is all this copying preventable with the current interface?
From memory, the context stack only needs to refer to already extant values at the moment, so it's probably possible to change it to the equivalent of std::pmr::vector<json::value const*>. (However, this might impede some future extensions that I have in mind. Either way, it's an optimization that doesn't depend on any interface changes.)

On Sun, 5 Feb 2023 at 04:56, Klemens Morgenstern via Boost <boost@lists.boost.org> wrote:
The formal review of the mustache starts today, Sunday the 5th, and ends next week on Tuesday the 14th.
Hi all, This is my review of Boost.Mustache. First of all, thanks Peter for submitting the library, and Klemens for volunteering as review manager.
- Does this library bring real benefit to C++ developers for real world use-case?
This is a utility library, and as such I do believe it has a place in Boost. Although Mustache is not super-popular, it comes up in certain contexts. I think having a robust Mustache engine, compatible with Describe and JSON, brings benefits to users.
- Do you have an application for this library?
Not right now. I'm thinking of writing a PoC pentesting software which may require templating HTTP requests with a list of payloads. If that happens to be the case, I'd use this library for that.
- Does the API match with current best practices?
It has a very small API surface, which I am really glad to see. It uses JSON as input format for data, which has both advantages (it's simple) and disadvantages (it doesn't allow to implement lambdas, it's not that extensible, and in its current form, it requires a lot of copying). I value simplicity a lot, so I'm alright with using JSON. However, I think the last point should be solved somehow. Template data is purely read-only, and efficiency should be a goal in a library like this. For these reasons, an API that allows the user to pass input data with minimal copies should exist. The partials argument doesn't seem to have the right type, as it must be a mapping from string to string, and the API declares it as a JSON object. If I'm not mistaken, by using JSON you're forcing the usage of UTF-8 for the input document. I think this is perfectly fine, but it should be documented. It may be worth exploring the option of providing a renderer::reset method that allows to recycle the same renderer, improving memory re-use. Is there any use case for passing a different output_ref to renderer::render_some and renderer::finish? If there isn't, output_ref could be passed to renderer's constructor.
- Did you try to use it? What problems or surprises did you encounter?
I've built the library, the tests and the examples with b2, Linux, gcc11 and with cmake, Linux, clang15 and libc++ with no problems. I had to add the example manually to the CMakeLists.txt, as cmake doesn't currently build the examples (the author is already aware of that). I've tried to break the library in every possible way I've imagined (especially with buffer overruns and XSS payloads) and I have failed, which is good. As described in previous emails, I found a couple of possible escaping-related problems that can constitute vulnerabilities. These are described in https://github.com/pdimov/mustache/issues/6 and should be easy to fix.
- What is your evaluation of the implementation?
I've navigated through most of it using a debugger, and I think it's fine. It seemed to me that it performed a lot of copies, so I performed some measurements. I measured the number and size of allocations performed through the storage_ptr's and I found it higher than expected. Input data being converted into json::value is one source for such allocations, and should be solved by the view-based API. The renderer class also performs a lot of copying while rendering. These allocations, however, seem to be avoidable without changing the interface. I've raised https://github.com/pdimov/mustache/issues/7 to address it.
- Is the documentation helpful and clear?
I've found reading the source code more helpful. This is what I would add: * A discussion section, similar to what URL does. I would include these sections: * Introductory usage example. Without Boost.Describe (as plain JSON is easier to understand for a newcomer). I would include some explanations on the Mustache features being used. I don't think a full section on Mustache is necessary, but saying "this is a tag", "this is a partial" would be useful. * Using the library with user-defined types - with Describe now. * Using renderer to render with render_some. * Using string types as output. * A section on escaping (the magic word "security" may help here). All other libraries have a bunch of open issues by users not understanding that escaping happens by default. Also, I would describe what "HTML escape" means in this context (the spec doesn't say it and different libs do different things). * A proper reference section, with links and human-readable explanations. Taking output_ref as an example, I would like to see: * A URL for output_ref, so you can reference it from other places in docs. * A human-readable explanation (e.g. "a polymorphic reference to either a string or a I/O stream that can be used to output a rendered Mustache template"). * Explanations of what St and Os mean (ideally, pointing to its own section). * When you reference other functions/classes (e.g. renderer in the render() description), please do provide links to them. Otherwise, the user ends up having to CTRL+F it, which is extremely frustrating (real story from mp11). * Doxygen comments (or similar). Pressing F12 and seeing comments on the function you're using helps. * Comparison to other libraries. Specially to the one listed by the official Mustache page, even if it seems to be unmaintained. * The documentation should state the exact version of the Mustache API that it's implementing. It would be good to briefly describe what "mandatory features" are in the spec, what optional features aren't implemented but are in the roadmap, and which ones won't happen. The spec is very difficult to read as a user, so don't expect people will read it.
- How much effort did you put into your evaluation? A glance? A quick reading? In-depth study?
I've dedicated around 10h to this review. I've read the docs, the Mustache discussion and spec, reviewed the Node library, built and run the examples, tried to break them, navigated through the impl via debugger and done the allocation study.
- Are you knowledgeable about the problem domain?
I briefly met Mustache when working with a swagger-codegen project (https://github.com/swagger-api/swagger-codegen). Given an OpenAPI spec, swagger-codegen generates stub code for you in different languages. I haven't used it from C++ or in production.
Please explicitly state that you either *accept* or *reject* the inclusion of this library into boost.
My recommendation is to **CONDITIONALLY ACCEPT** this library into Boost, with the following conditions: 1. The partials argument must be typed according to the data structure it requires. 2. A view-based API should be added or, at least, should be addable without breaking changes. 3. The found vulnerabilities must be fixed. 4. Proper documentation must be written. Some other minor points (these are not acceptance conditions): * The link to mustache.github.io in the docs is HTTP instead of HTTPS. * Calling a type in the examples "reference" may not be the best idea. I stared at it thinking "why is this not dangling" until I figured out what "reference" meant in that context. * Is the config header supposed to be included by users? If not, move to detail/ * Is output_ref::write supposed to be called by users? If not, make it private. * Not being able to load the CML without the superproject contributes to the feeling of living in a monolith. * Your copyright is out of date ;) Regards, Ruben.

Vinnie Falco wrote:
On Thu, Feb 9, 2023 at 6:52 AM Peter Dimov via Boost <boost@lists.boost.org> wrote:
I don't see how this is supposed to be accomplished.
boost::json::object&& perhaps?
That's not what the function takes. std::map<std::string, std::string> is a valid argument, for instance.

On Sat, Feb 4, 2023 at 9:56 PM Klemens Morgenstern via Boost <boost@lists.boost.org> wrote:
Review ========
Please explicitly state that you either *accept* or *reject* the inclusion of this library into boost. The accept can be conditional.
The documentation is not usable as it is. There's just too much missing to use the library past the simplest use cases. Having said that, the implementation is good and up to par for Boost, AFAICT. My conclusion is to CONDITIONALLY ACCEPT. The condition being to write all the missing documentation.
Also please indicate the time & effort spent on the evaluation and give the reasons for your decision.
I spent about 4 hours in total reviewing the library. I read the documentation, playing around with the examples, and reading the code. I made some minor changes to the build files to incorporate into my ongoing work to adjust the Boost libraries to be fully modular with B2. The project built without warnings, errors, or any problems at all. So kudos for that.
Some questions to consider:
- Does this library bring real benefit to C++ developers for real world use-case?
Yes. Some form of templating output is ubiquitous if one needs to do any form of input processing to generate textual output.
- Do you have an application for this library?
Not immediately. I have some near future use cases for tooling that I was considering something like this. Specifically in generating data matching tooling metadata (compile commands data, package description data, compiler response data, for ecosystem IS reference implementations). My use cases required being able to exchange the output format without changing the input so that I could output XML, JSON, YAML, etc by only changing the templates (ideally).
- Does the API match with current best practices?
What I understand of the API, yes. But that's just the "render" and using Json.
- Is the documentation helpful and clear?
No. While I'm okay with the documentation only referencing the mustache spec. I'm not fine with the essentially zero explanation of what the facility does. Some questions I had while reading the documentation: * How would it work if I don't use Boost.Describe? * Should I know where in the Json docs I should look for further answers? * How do I use "render_some"? * Why should I care about the "output_ref" API? I.e: What's for other than it's the argument to "render_some"? I did figure out most of the answers to the questions after reading the test sources and implementation. But one shouldn't need to do that to use a library.
- Did you try to use it? What problems or surprises did you encounter?
No. Looking at the examples and tests was enough for me to understand what was going on. And more importantly if it would fit the use cases I'm looking to solve.
- What is your evaluation of the implementation?
It is clean and straightforward. I learned some things about core::string_view I didn't know (which I might use in B2 since I copied that implementation for use there). While the comments are minimal. They are also sufficient. -- -- René Ferdinand Rivera Morell -- Don't Assume Anything -- No Supone Nada -- Robot Dreams - http://robot-dreams.net

Le dimanche 05 février 2023 à 11:55 +0800, Klemens Morgenstern via Boost a écrit :
The formal review of the mustache starts today, Review ========
Hi. This is my review of the proposed boost.mustache library. To put some context, I'm not particularly knowledgeable of templating libraries, i have been using jinja for small tasks, and that's nearly all. Writing this review was the occasion to dig more in this area, and I wish to thank Peter for proposing the library.
Please explicitly state that you either *accept* or *reject* the inclusion of this library into boost. The accept can be conditional.
I think this library should be REJECTED for boost inclusion in its current state. I think there are too many defects that needs to be addressed before inclusion. However, I think a templating engine would be a nice addition, so I would like this library to evolve and be proposed again for inclusion in boost.
Also please indicate the time & effort spent on the evaluation and give the reasons for your decision.
I have spent between 8 and 10 hours I think, across several days (which makes it hard to track an exact count), reading the documentation, the documentation on mustache, reading the source code and playing with toy projects to evaluate the library.
* Do you have an application for this library?
I currently maintain a python script which generate some code from description files in yaml format, using jinja2 templates. I would be happy to use a C++ tool for that, which would avoid those python dependencies on the build server. Unfortunately, i came to the conclusion that the proposed library is not a good fit.
* Does this library bring real benefit to C++ developers for real world use-case?
A templating engine is a useful tool. I have some concerns, however, whether mustache is a good enough/adequate template language. The concerns are as follows: - html escaping by default. This is the kind of design decision that tend to show the language was not designed for general use. I also fail to see how that's supposed to work in real-life: html documents are heterogeneous, and several of their sections have different encoding rules (embedded css or scripts, url arguments, just to name a few). To me, it looks like php magic_quotes: the kind of ideas that are inherently bad, and will only cause more trouble than the problem they're trying to solve. - no specification of encoding. I'm ok with utf-8 only, but that ought to be specified somewhere. - the lack of filters (like jinja filters). Filters are a nice way to transform the data at the point where it is used. This could be used for value escaping (actually, this is how we use it to generate valid c++ identifiers from values in our yaml description files). - it is very hard to generate correctly a comma separated list of values using mustache templates. This is not a so uncommon need, there ought to be a canonical simple way to do that. - this is a lesser concern, but the specification of mustache templating language is unreadable as hell. I really wished there were a RFC instead of this list of yml files. And why isn't a template provided to format them in a really human readable format, and the result widely available on a web page? I just wonder...
* Does the API match with current best practices?
The API is rather simple. It uses string_view when possible, modern stuff, etc. But I was surprised to see the logic. If I were to implement a templating engine (which is something I've never done, so I may be completely wrong on this), I would first compile the template into an internal memory representation, and then apply that compiled template to different data, reusing the parsing work done (something similar to SQL prepared statements). This approach is somehow also suggested by mustache(5) man page, which tells that partials “are rendered at runtime (as opposed to compile time)”. So, there could be a compile phase. But that's not the case with boost.mustache: everything is rendered at runtime. This is not an issue per-se: it works fine, even when the template is read by blocks (ie, the template is not fully available during the rendering - I guess supporting this use case may have lead to these design decisions). However, there are some oddities: - when building a renderer object, you need to feed them the partials, and the data. But obviously, the partials implementation is going to depend on your template. Let's say i wish to export the same set of data to different output formats, like markdown and html, i could use the same renderer with different templates. But that's not the case, as the partials are likely to differ as well. - the API requires json objects, or converts them to json. Playing with the HTML example, I changed: boost::mustache::render( html, std::cout, ref, { { "header", header }, { "footer", footer }, { "item", item}, { "body", body } } ); to boost::mustache::renderer rd(ref, { { "header", header }, { "footer", footer }, { "item", item }, { "body", body } } ); rd.render_some(html1, std::cout); rd.finish(std::cout); (as suggested by the documentation). To my surprise, it failed to compile. Fixing that was easy, but it made me wonder if the current approach was a good one. I see no reason for partials to be a json_object: they could be anything that maps a string with another (a map<string,string> being a reasonable choice, but it would make sense to also support map<string_view, string_view>). The problem is that they are currently stored at render object creation, so i understand why the hardcoding of the type. But i think the wrong one was chosen here. - the renderer takes ownership of the json data. I see plenty of cases where i will not want this, as it will require an extra copy. - the current API makes it very difficult to integrate lambdas, which could be a way to work around several limitations of the templating language. - the output_ref concept has no way to indicate that it is full, to specify a maximum size, or to report how many characters it has actually written. This is an issue, because it makes buffered output nearly impossible. There's no way, given the input, to correctly predict the output size. The library correctly handles slicing the input template, but won't be able to slice its output, and resume it later. This is likely to cause integration issues. I would prefer the opposite choice (ie, the whole input template must reside in memory, but slicing of the output is supported). And, the worse in my opinion is that there is no error reporting mechanism. The mustache man page tells that a variable “miss” returns an empty string, but that it is usually configurable. Unfortunately, it is not with boost.mustache, which will always silently use an empty string. Worse, it also do it for partials (for which I fail to see what the requirements are supposed to be in the documentation). There should be a rendering policy to select the behaviour in case these events occurs.
* Is the documentation helpful and clear?
The documentation is OK if you want a quick way to generate a simple document. However, it lacks several sections: - design decisions. Why is there no “compilation” phase to reuse templates? Note that the templating language itself lacks a description on its design decisions (why having lambdas instead of filters, for example?) - performance. There is no section on how the library performs, compared to other implementations. There is also no guidance on how to efficiently use the library. If I'm doing html templating server-side, this is obviously something that i will look into. - there is no section on memory handling -> what are the allocation strategies, how much parsing and rendering a template allocates, etc. (ideally, rendering a template should not allocate memory — excluding memory allocated by the output_ref — unless partials are in use). - the render_some supports slicing the input. But that's not documented. It is also not documented what i gain by using this api instead of the render function (what can be reused?) - given that the overall documentation on mustache templating language is pretty bad, some effort could be made to take it to a better level. - error handling. I see two types of errors: - missing variables/partials in template resolution (I already talked about this) - template errors. I'm not sure these ones exist, my understanding is that mustache is designed so that anything that would be a parse error is just “non-mustache” and rendered as-is. But nowhere it is documented.
* Did you try to use it? What problems or surprises did you encounter?
I used it only in an evaluation context, for the review. No problems outside those mentioned.
* What is your evaluation of the implementation?
I did not have more than a quick look at it. I've found a few surprising things at glance (but since this is not a deep review, they may be incomprehensions/mistakes on my side): - the json::string whitespace_ . I fail to see why there is a specific handling for leading spaces, and why the parser does not start into state_passthrough. I was wondering also why just counting the spaces was insufficient, but it seems to be related to handling both ' ' and '\t'. - the data object is stored as non-const in the context stack. I have already mentioned this in the API comments, these extra copies are going to be issues. - the context stack is a json::array. Unless i'm mistaken, this means that entering a section will cause a copy of the subobject, on top of the context stack. Since the object is not altered by the renderer, storing a pointer to the subobject in the context stack should be enough, and would avoid a copy. - html escaping is not done correctly in all cases ('\r', for example, should be escaped in the output). I did not look further, as I think most of these are implementation issues that can be fixed later, unlike the API/design choices that motivates my refusal. Coming to a conclusion, I think the following question should be answered: - what is the purpose of this library? Like in, “do we want a templating mechanism available, or do we want a strict mustache conforming implementation?” I think the former would provide great value to boost. However, it would mean evaluating different template languages available, evaluating the use cases we want to support, and taking design decisions accordingly. Mustache can be a starting point, i don't know how badly specified are other template languages. On the other side, if what we want is the latter, then the roadmap would be different: fix the few design issues, add lambda support, write all missing documentation, and integrate to boost. But to me, it would look like a missed opportunity: contrary to what the mustache authors claims, mustache is *not* a templating system for anything. It has just far too many limitations and design failures that needs to be circumvented for this. Someone in a review looks forward using this library to produce xml or json only by changing the templates: I wish him good luck with that. My opinion on this is that's it's not reasonably doable with mustache... Regards, Julien

Julien Blanc wrote:
Fixing that was easy, but it made me wonder if the current approach was a good one. I see no reason for partials to be a json_object: they could be anything that maps a string with another (a map<string,string> being a reasonable choice, but it would make sense to also support map<string_view, string_view>).
But they can be. Try it. int main() { std::string template_( "{{>part}}" ); std::map<std::string, std::string> partials{ { "part", "something" } }; boost::mustache::render( template_, std::cout, {}, partials ); }

On Sat, 18 Feb 2023, 13:34 Peter Dimov via Boost, <boost@lists.boost.org> wrote:
Julien Blanc wrote:
Fixing that was easy, but it made me wonder if the current approach was a good one. I see no reason for partials to be a json_object: they could be anything that maps a string with another (a map<string,string> being a reasonable choice, but it would make sense to also support map<string_view, string_view>).
But they can be. Try it.
int main() { std::string template_( "{{>part}}" ); std::map<std::string, std::string> partials{ { "part", "something" } };
boost::mustache::render( template_, std::cout, {}, partials ); }
Does this not copy the map into a json object? Thanks, Ruben.

Ruben Perez wrote:
On Sat, 18 Feb 2023, 13:34 Peter Dimov via Boost, <boost@lists.boost.org <mailto:boost@lists.boost.org> > wrote:
Julien Blanc wrote:
Fixing that was easy, but it made me wonder if the current approach was a good one. I see no reason for partials to be a json_object: they could be anything that maps a string with another (a map<string,string> being a reasonable choice, but it would make sense to also support map<string_view, string_view>).
But they can be. Try it.
int main() { std::string template_( "{{>part}}" ); std::map<std::string, std::string> partials{ { "part", "something" } };
boost::mustache::render( template_, std::cout, {}, partials ); }
Does this not copy the map into a json object?
It does.

Julien Blanc wrote:
Coming to a conclusion, I think the following question should be answered: - what is the purpose of this library? Like in, “do we want a templating mechanism available, or do we want a strict mustache conforming implementation?”
I think the former would provide great value to boost. However, it would mean evaluating different template languages available, evaluating the use cases we want to support, and taking design decisions accordingly. Mustache can be a starting point, i don't know how badly specified are other template languages. On the other side, if what we want is the latter, then the roadmap would be different: fix the few design issues, add lambda support, write all missing documentation, and integrate to boost. But to me, it would look like a missed opportunity: contrary to what the mustache authors claims, mustache is *not* a templating system for anything. It has just far too many limitations and design failures that needs to be circumvented for this. Someone in a review looks forward using this library to produce xml or json only by changing the templates: I wish him good luck with that. My opinion on this is that's it's not reasonably doable with mustache...
At this juncture, the choice is between having Mustache in Boost and not having Mustache in Boost. It's not between having Mustache and having something else, because nothing else has been developed and proposed. I should also note that having Mustache in Boost does not in any way preclude having something else too, in the event that something else is developed and proposed.

Julien Blanc wrote:
The API is rather simple. It uses string_view when possible, modern stuff, etc. But I was surprised to see the logic. If I were to implement a templating engine (which is something I've never done, so I may be completely wrong on this), I would first compile the template into an internal memory representation, and then apply that compiled template to different data, reusing the parsing work done (something similar to SQL prepared statements). This approach is somehow also suggested by mustache(5) man page, which tells that partials “are rendered at runtime (as opposed to compile time)”. So, there could be a compile phase. But that's not the case with boost.mustache: everything is rendered at runtime. This is not an issue per-se: it works fine, even when the template is read by blocks (ie, the template is not fully available during the rendering - I guess supporting this use case may have lead to these design decisions).
That is exactly the reason. Since the template is rendered on the fly, without a requirement for it being fully available, it's not possible to construct a parse tree first.
- the json::string whitespace_ . I fail to see why there is a specific handling for leading spaces, and why the parser does not start into state_passthrough. I was wondering also why just counting the spaces was insufficient, but it seems to be related to handling both ' ' and '\t'.
Mustache has the concept of a "standalone tag", a tag that doesn't produce any output and is preceded and followed by whitespace and a newline, and it requires the whitespace surrounding the standalone tag to not be output. Since (long ago) I wrote my own template engine that didn't have this rule I understand why it's useful and how it makes the output prettier, but it's a pain to implement correctly. I have tests that check the official "specification" test cases directly, and all these whitespace_ shenanigans are necessary to make them pass.

Julien Blanc wrote:
- the lack of filters (like jinja filters). Filters are a nice way to transform the data at the point where it is used. This could be used for value escaping (actually, this is how we use it to generate valid c++ identifiers from values in our yaml description files).
Interestingly, while thinking about the issues Rainer Deyke raised, I effectively seem to have reinvented Jinja filters, right down to the name and syntax. They are a straightforward extension and will solve (or at least mitigate) much of the deficiencies of the language.

Are you knowledgeable about the problem domain? I have been using several text templating engines written in Python in
This is my review of Boost.Mustache. the past, and I still use them occasionally for small tasks.
How much effort did you put into your evaluation? A glance? A quick reading? In-depth study? Overall, about 8 hours over several days.
Does this library bring real benefit to C++ developers for real world use-case? Generating text from a template has a multitude of applications.
Do you have an application for this library? I thought I do, but turns out that I don't. And this has to do with the severe inadequacy of the Mustache language. It is very simple and minimal and is very cute in its simplicity. But this simplicity makes it almost impossible to do very common tasks.
Does the API match with current best practices? When reading documentation I considered it strange that there is no non-throwing versions of render and render_some. Turns out this is because parsing never fails, or at least, this is my impression, because I've not managed to make it fail. I find this weird. I think
I started this review with an attempt to reimplement an existing script that I had that created an HTML page. But the very first templating element I needed was inexpressible in Mustache, because I needed to have a special case for the first element of a list. I realised that I had to tailor my input data for the specific needs of Mustache language. My second attempt was focused on trying to do that: structuring data in the way Mustache can handle. This is where I realised that Mustache doesn't play nice with the way Boost.JSON converts maps. If a map has unique string-like keys Boost.JSON converts it to a json::object. But Mustache doesn't treat them as sequences, it treats them as context switches. I briefly considered switching to multimaps, which can have non-unique keys and thus are converted to json::array of pairs. But pairs are also converted to arrays by Boost.JSON, and as we've previously established, Mustache cannot have a special treatment of the first or the last element of a sequence. that syntax errors should be reported to the user. I also find it very useful, when failed variable lookup is reported, and so I believe, there needs to be some mechanism to enable that. I think that using Boost.JSON containers for rendering context was a very interesting decision, particularly because it enables a lot of synergy. I believe the amount of copying it results in should be negligible for most applications, and for others often a good allocator would greatly reduce the amount of actual memory allocations, so I'm not concerned with that too much. On the other hand, the use of Boost.JSON did result in inability to support Mustache lambdas, which could somewhat alleviate the language's inadequacy.
Is the documentation helpful and clear? The documentation is too minimalistic. There should be more examples starting with the most simple tasks, and gradually introducing more complexity.
What is your evaluation of the implementation? I haven't spent much time looking through the implementation.
Do you think the library should be accepted as a Boost library? I think the library should be REJECTED almost entirely due to the weakness of the Mustache language. There is a variation of Mustache called Handlebars that has more features. In particular, it can iterate over objects, allows accessing the iteration number in a loop, has an if statement, and allows registering custom functions and custom statements (which solves the lack of Mustache lambdas). I would encourage Peter to implement that language and submit the new library for review.
вс, 5 февр. 2023 г. в 06:56, Klemens Morgenstern via Boost <boost@lists.boost.org>:
The formal review of the mustache starts today, Sunday the 5th, and ends next week on Tuesday the 14th.
The library was developed & submitted by Peter Dimov.
Boost.Mustache is an implementation of Mustache templates in C++11.
The master branch is frozen during the review and can be found here https://github.com/pdimov/mustache
The current documentation can be found here: https://pdimov.github.io/mustache/doc/html/mustache.html
Boost.Mustache is an implementation of Mustache templates in C++11.
The documentation of Mustache templates is here: https://mustache.github.io/
Review ========
Please explicitly state that you either *accept* or *reject* the inclusion of this library into boost. The accept can be conditional.
Also please indicate the time & effort spent on the evaluation and give the reasons for your decision.
The review is open to anyone who is prepared to put in the work of evaluating and reviewing the library. Prior experience in contributing to Boost reviews is not a requirement.
Some questions to consider:
- Does this library bring real benefit to C++ developers for real world use-case? - Do you have an application for this library? - Does the API match with current best practices? - Is the documentation helpful and clear? - Did you try to use it? What problems or surprises did you encounter? - What is your evaluation of the implementation?
More information about the Boost Formal Review Process can be found at: http://www.boost.org/community/reviews.html
Reviews can also be submitted directly to me.
Thank you Peter for submitting yet another boost library & thanks for all the reviews in advance.
Building boost.mustache =======================
Here's how to build the library, starting from scratch:
1. Clone Boost from Github:
git clone --recurse-submodules https://github.com/boostorg/boost
2. Clone the Mustache library into the Boost tree:
cd boost/libs git clone https://github.com/pdimov/mustache cd ..
3. Build b2:
./bootstrap.sh
(We assume Linux and g++ from now on. On Windows, it's just `booststrap`.)
4. Generate the header links in the boost/ directory:
./b2 headers
5. Build the Mustache library and its dependencies (e.g. JSON):
./b2 --with-mustache
This will place the compiled libraries into the stage/lib directory. It should contain libboost_container.a/.so, libboost_json.a/.so, and liboost_mustache.a/.so.
You can now build and run the Mustache examples by using e.g.
g++ libs/mustache/example/html.cpp -o html -I . -L stage/lib -lboost_mustache -lboost_json
./html
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hello Boost Community, my review on this mustache library. TLDR: CONDITIONALLY ACCEPT Conditions mostly on the documentation, I think the further evolution of this library will happen naturally once it is in boost and gets picked up by users. Review time: about 2 hours First, I understand that this is kinda niche, and most folks never will have a usecase for this in their career. Maybe also because such a library is not available to them. So I've spend some time to read the debate and followed along, wondering if I'd write this review, as I do actually have a use case. I'm a boostache user. In 2014, during C++now this library was created and in later works extended, it is exactly what this new mustache library does: a mustache library for boost. boostache is still on github for you to see https://github.com/cierelabs/boostache Sadly, boostache never went to review and has been a little known library used by very few users afaik. My use case is that this powers the part of the CMS where text templates are being used to create the actual website in html code. I did write this code years ago, and only can scratch the surface of this, but mostly interfacing to boostache has been done via its basic data interface: maps and fusion adapted types if I remember correctly. On the first view boost::mustache looks like a modern replacement for boostache. I can understand that some of the interfaces go for boost::json, but wonder if boostache went a more lightweight way here with simply having a map<string,variant>. Maybe the boost json type is exactly this or similar. But maybe mustache can learn from boostache, and take add some its interfaces to make transition to a more modern version of a C++ mustache library easier for the users. From the documentation I think that it is a fairly simple library at the moment, which may see added features and growth from being in boost. Using boost::Describe feels right, making the library based on C++11 makes it available for many users. Supporting boost::json is great, but I wonder if its really the best from the usability stand point, does one have to be familiar with boost::json to use this library? I think the library should take the comparison to boostache, which has more examples in the documentation, and this is where I agree with prior comments: please add more examples and explanations. One of the biggest headaches with boostache was the compilation time, so I'm glad to see that this library has an implementation based on a cpp file.
Some questions to consider:
- Does this library bring real benefit to C++ developers for real world use-case? Yes, I think so. In any context you have text templates that have various values to be generated.
- Do you have an application for this library? My CMS. meetingcpp.com is currently build as a static website with boostache. - Does the API match with current best practices? For C++11 yes. I assume that boost::string_view is able to convert automatically from std::string_view so that the library plays nice with more modern code bases. - Is the documentation helpful and clear? Yes, but I think it should be updated. - Did you try to use it? What problems or surprises did you encounter? I currently don't have a setup to do this, what I can contribute is my experience with boostache and comparing how the code and supported mustache files look and if this library would be able to replace them. I lack the time to setup a test for this at the moment. - What is your evaluation of the implementation? As stated, the compilation times with boostache weren't so great, so I think its a good start to see that the library actually has an cpp implementation file. It would be a good idea to run a fuzzer on the implementation, as it parses text.
thanks, Jens Weller

On Sat, Feb 18, 2023 at 4:16 PM Jens Weller via Boost <boost@lists.boost.org> wrote:
So I've spend some time to read the debate and followed along, wondering if I'd write this review, as I do actually have a use case. I'm a boostache user. In 2014, during C++now this library was created and in later works extended, it is exactly what this new mustache library does: a mustache library for boost. boostache is still on github for you to see https://github.com/cierelabs/boostache
Sadly, boostache never went to review and has been a little known library used by very few users afaik. My use case is that this powers the part of the CMS where text templates are being used to create the actual website in html code. I did write this code years ago, and only can scratch the surface of this, but mostly interfacing to boostache has been done via its basic data interface: maps and fusion adapted types if I remember correctly.
On the first view boost::mustache looks like a modern replacement for boostache. I can understand that some of the interfaces go for boost::json, but wonder if boostache went a more lightweight way here with simply having a map<string,variant>. Maybe the boost json type is exactly this or similar. But maybe mustache can learn from boostache, and take add some its interfaces to make transition to a more modern version of a C++ mustache library easier for the users.
Just wanted to comment on this here, since boostache was a library in a week invention. The most important innovation in boostache in my view was the fact that it did not require conversion of a data structure into a map-like data structure prior to output. The classic Google template (a mustache engine from years ago) and most others I'd ever seen required this step. Unfortunately, I didn't have time to look at boost::mustache in detail, but from my quick look it appears the use of Describe also enables this direct to format feature. I'll note that the need for this sort of engine is now much less with std:format and friends -- which includes range-based output. Json object output can be trivially and effficiently written with std::format. I'd also argue that the biggest issue I've had with mustache based output systems is the lack of format control at the template level. What it leads to is an explosion of tags for different formats in different types of templates. If we were to have a templating system I'd like to see it natively support formatting. Jeff

Jeff Garland wrote:
Just wanted to comment on this here, since boostache was a library in a week invention. The most important innovation in boostache in my view was the fact that it did not require conversion of a data structure into a map-like data structure prior to output. The classic Google template (a mustache engine from years ago) and most others I'd ever seen required this step. Unfortunately, I didn't have time to look at boost::mustache in detail, but from my quick look it appears the use of Describe also enables this direct to format feature.
As is, the proposed Mustache library does take any "reasonable" UDT as the input data. so purely from the user point of view it "works", but implementation-wise, this is accomplished by converting the UDT into a json::value using boost::json::value_from. This isn't efficient, but fixing that is nontrivial and has repercussions on the rest of the library, including future extensions such as the aforementioned filters. (Not caring about copies makes the design much more flexible, e.g. the user-supplied filter functions can just take and return json::value, without ever knowing about UDTs.)

Thanks for the detailed clarification. The main thing in my view is that the map<string,any> part isn't the 'required user interface" like many of the older library designs. Jeff On Sun, Feb 19, 2023 at 10:27 AM Peter Dimov via Boost < boost@lists.boost.org> wrote:
Just wanted to comment on this here, since boostache was a library in a week invention. The most important innovation in boostache in my view was the fact that it did not require conversion of a data structure into a map-like data structure prior to output. The classic Google template (a mustache engine from years ago) and most others I'd ever seen required this step. Unfortunately, I didn't have time to look at boost::mustache in detail, but from my quick look it appears the use of Describe also enables this direct to
Jeff Garland wrote: format
feature.
As is, the proposed Mustache library does take any "reasonable" UDT as the input data. so purely from the user point of view it "works", but implementation-wise, this is accomplished by converting the UDT into a json::value using boost::json::value_from.
This isn't efficient, but fixing that is nontrivial and has repercussions on the rest of the library, including future extensions such as the aforementioned filters.
(Not caring about copies makes the design much more flexible, e.g. the user-supplied filter functions can just take and return json::value, without ever knowing about UDTs.)
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Sun, 5 Feb 2023, 1:56 pm Klemens Morgenstern via Boost, < boost@lists.boost.org> wrote:
The formal review of the mustache starts today, Sunday the 5th, and ends next week on Tuesday the 14th.
The library was developed & submitted by Peter Dimov.
Boost.Mustache is an implementation of Mustache templates in C++11.
This is useful. I've used Mustache before and while its specification is somewhat quirky and in particular oriented towards html templating, this usage is a genuinely common, and also non-trivial use case. Having easy to use support for this with/in C++ helps to make C++ usable in a web "world" for user facing purposes with server side rendering. That said, I have used this type of templating for "plain text" and JSON as well as HTML. Specifically where a configuration file specifies a template used with runtime parameters. In future I would use this library for such purposes as well as in a html context. No doubt there are many other uses for simple templating capabilities.
Review ========
Please explicitly state that you either *accept* or *reject* the inclusion of this library into boost. The accept can be conditional.
Conditionally ACCEPT. The condition is to provide documentation that is stand alone from external Mustache documentation, sufficient to understand and use the library and not require reference to external documentation for terms used in Mustache. I would like to see (but this isn't a condition) separation of the output rendering/escaping to allow customisation - not only the choices in the Mustache specification. I would like to see lambda support but that's an interesting area to consider as an extension of boost.json (to allow values that are functors taking and returning a json type).
Also please indicate the time & effort spent on the evaluation
A few hours. Reviewed the implementation (clean, simple, and by relying on describe and json libs providing a consistent (with other use of structured data in a program) and capable interface.
and give the reasons for your decision.
- Does this library bring real benefit to C++ developers for real world use-case?
Yes as outlined above it has utility. And its use of describe and json as vocabluary type is preferable to the alternative presented by the mstch library.
- Do you have an application for this library?
Yes as outlined.
- Does the API match with current best practices?
Yes.
- Is the documentation helpful and clear?
Yes but too much reliance on the less than helpful and clear external Mustache documentation.
- Did you try to use it? What problems or surprises did you encounter?
No. I had no immediate need to change existing code. I was pressed for time and sufficiently convinced by the implementation and examples to see what was in the packet and that it did what it said.
- What is your evaluation of the implementation?
It's small, clean and has a similarly small and clean interface. I like it. The efficiency issues arising from the reliance on/conversion to/through the boost.json vocabulary type are somewhere between non-existent (I have a real use case for rendering from a received json object) and acceptable (boost.json is efficient as such things go). The async/streaming capabilities and clean interface using existing vocabulary types (vocabulary meta-types in case of describe?) of the library are more important to me than the very last bit of efficiency. Regards Darryl Green.
participants (20)
-
Darryl Green
-
Dominique Devienne
-
Gavin Lambert
-
Glen Fernandes
-
Ion Gaztañaga
-
Jeff Garland
-
Jens Weller
-
jepessen@wteam.it
-
Julien Blanc
-
Klemens Morgenstern
-
Mateusz Loskot
-
Peter Dimov
-
Rainer Deyke
-
René Ferdinand Rivera Morell
-
Richard
-
Robert Ramey
-
Ruben Perez
-
Vinnie Falco
-
William Linkmeyer
-
Дмитрий Архипов