LCOV - code coverage report
Current view: top level - src/tools/kdb/gen - template.hpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 12 24 50.0 %
Date: 2019-09-12 12:28:41 Functions: 8 15 53.3 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  */
       8             : 
       9             : #ifndef ELEKTRA_KDB_GEN_TEMPLATE_HPP
      10             : #define ELEKTRA_KDB_GEN_TEMPLATE_HPP
      11             : 
      12             : #include "mustache.hpp"
      13             : 
      14             : #include <algorithm>
      15             : #include <iostream>
      16             : #include <memory>
      17             : #include <unordered_map>
      18             : #include <unordered_set>
      19             : 
      20             : #include <kdb.hpp>
      21             : #include <kdbmacros.h>
      22             : 
      23             : class EmptyGenTemplate;
      24             : 
      25             : /**
      26             :  * A template for the gen command.
      27             :  */
      28             : class GenTemplate
      29             : {
      30             : protected:
      31             :         /**
      32             :          * Construct a new template for the gen command.
      33             :          *
      34             :          * A template may consist of multiple parts.
      35             :          * All mustache files for this template must start with @p templateBaseName,
      36             :          * and end with ".mustache". The part in between is determined by an entry in @p parts.
      37             :          *
      38             :          * @param templateBaseName The basename for all mustache files associated with this template.
      39             :          * @param parts            The suffixes of the different parts associated with this template. Most of the time
      40             :          *                         a part corresponds to a mustache file. However, you may return false in
      41             :          *                         getTemplateData() for output files that do not have mustache templates and you can
      42             :          *                         override getParts() to remove parts. This argument should contain the full list of
      43             :          *                         possible parts.
      44             :          *                         Pass `{ "" }` if this template only uses a single file, identified by the @p templateBaseName.
      45             :          * @param parameters       The list of parameters this template uses. The keys are the names, while the value
      46             :          *                         determines whether the parameter is required or not (true means required).
      47             :          */
      48             :         GenTemplate (std::string templateBaseName, std::vector<std::string> parts, std::vector<std::string> partials,
      49             :                      const std::unordered_map<std::string, bool> & parameters);
      50             : 
      51             :         /**
      52             :          * Construct the mustache template data from the given snapshot of the KDB.
      53             :          *
      54             :          * @param outputName the basename of all output files. The output files are expected to use the same names
      55             :          *                   as the template files, except that `templateBaseName` is replaced by @p outputName.
      56             :          * @param part       the part suffix for the current part
      57             :          * @param ks         A KeySet containing the data for this template. All keys are below @p parentKey.
      58             :          * @param parentKey  The parent key below which the data for this template resides.
      59             :          *
      60             :          * @return The mustache data needed to render this template.
      61             :          *         If the returned data is false (i.e. kainjow::mustache::data::is_false() returns true), render() will
      62             :          *         not invoke mustache rendering for this part. In this case you should write something to the output
      63             :          *         file of this part before returning false.
      64             :          */
      65             :         virtual kainjow::mustache::data getTemplateData (const std::string & outputName, const std::string & part, const kdb::KeySet & ks,
      66             :                                                          const std::string & parentKey) const = 0;
      67             : 
      68             :         /**
      69             :          * Get the value of a parameter.
      70             :          *
      71             :          * @param name         The parameter name
      72             :          * @param defaultValue The default value
      73             :          *
      74             :          * @return the value of the parameter or @p defaultValue, if it wasn't set or is unknown
      75             :          */
      76             :         std::string getParameter (const std::string & name, const std::string & defaultValue = "") const;
      77             : 
      78             :         /**
      79             :          * Get the boolean value of a parameter.
      80             :          * The allowed values are 0 for false and 1 for true.
      81             :          *
      82             :          * @param name         The parameter name
      83             :          * @param defaultValue The default value
      84             :          *
      85             :          * @return the value of the parameter or @p defaultValue, if it wasn't set or is unknown
      86             :          */
      87             :         bool getBoolParameter (const std::string & name, bool defaultValue = false) const;
      88             : 
      89             :         /**
      90             :          * Get the value of a parameter with limited allowed values.
      91             :          *
      92             :          * The value of the parameter will be searched in @p values. If found, the mapped value is returned,
      93             :          * otherwise a std::invalid_argument is thrown. If the parameter isn't set, or is unknown to the template,
      94             :          * this function looks for the empty string in @p values.
      95             :          *
      96             :          * @param name         The parameter name
      97             :          * @param values       The allowed values
      98             :          *
      99             :          * @return the mapped value of the parameter
     100             :          *
     101             :          * @throws std::invalid_argument
     102             :          */
     103             :         template <class T>
     104         108 :         T getParameter (const std::string & name, const std::unordered_map<std::string, T> & values) const
     105             :         {
     106             :                 // has to be in header for template to work
     107         540 :                 std::string param = getParameter (name);
     108         108 :                 auto value = values.find (param);
     109         216 :                 if (value == values.end ())
     110             :                 {
     111           0 :                         throw std::invalid_argument (param);
     112             :                 }
     113         216 :                 return value->second;
     114             :         }
     115             : 
     116             :         /**
     117             :          * The escape function used when instantiating the mustache templates. Override to customise.
     118             :          *
     119             :          * @param str an unescaped value
     120             :          *
     121             :          * @return the escaped version of @p str
     122             :          */
     123             :         virtual std::string escapeFunction (const std::string & str) const;
     124             : 
     125             :         /**
     126             :          * @return A list of parts of which this template consists.
     127             :          *         By default this is the full list of parts given in the constructor. It may be overriden,
     128             :          *         to dynamically remove parts based on the parameters for this template. Adding parts here
     129             :          *         will not work, because render() only evaluates the parts given in the constructor.
     130             :          *
     131             :          *         The returned list also dictates the order in which parts should be rendered.
     132             :          */
     133             :         virtual std::vector<std::string> getActualParts () const;
     134             : 
     135             : public:
     136             :         /**
     137             :          * @retval true if this is the empty template
     138             :          * @retval false otherwise
     139             :          */
     140           9 :         virtual bool isEmpty () const
     141             :         {
     142           9 :                 return false;
     143             :         }
     144             : 
     145             :         /**
     146             :          * Set the value of a parameter.
     147             :          *
     148             :          * @param name The parameter name
     149             :          * @param value The new parameter value
     150             :          */
     151             :         void setParameter (const std::string & name, const std::string & value);
     152             : 
     153             :         /**
     154             :          * Clears the parameters values set on this template.
     155             :          */
     156             :         void clearParameters ();
     157             : 
     158             :         /**
     159             :          * Loads the list of actual parts, based on the current parameters.
     160             :          * Must be called before rendering, if parameters have been set.
     161             :          */
     162             :         void loadParts ();
     163             : 
     164             :         /**
     165             :          * @return A list of parts of which this template consists.
     166             :          *         The returned list dictates the order in which parts should be rendered.
     167             :          */
     168             :         const std::vector<std::string> & getParts () const;
     169             : 
     170             :         /**
     171             :          * Render a part of this template using the given snapshot of the KDB into the given stream.
     172             :          *
     173             :          * @param output     The stream to which the render result shall be written.
     174             :          * @param outputName the basename of all output files. The output files are expected to use the same names
     175             :          *                   as the template files, except that `templateBaseName` is replaced by @p outputName.
     176             :          * @param part       The name of the part to be rendered.
     177             :          *                   No output will be generated, if this isn't an element of getParts().
     178             :          * @param ks         A KeySet containing the data for this template. Probably resulting from a call to KDB#get.
     179             :          * @param parentKey  The parent key below which the data for this template resides.
     180             :          */
     181             :         void render (std::ostream & output, const std::string & outputName, const std::string & part, const kdb::KeySet & ks,
     182             :                      const std::string & parentKey) const;
     183             : 
     184          36 :         virtual ~GenTemplate () = default;
     185             : 
     186             : private:
     187             :         std::string _templateBaseName;
     188             :         std::vector<std::string> _allParts;
     189             :         std::vector<std::string> _parts;
     190             :         std::vector<std::string> _partials;
     191             :         std::unordered_map<std::string, std::string> _parameters;
     192             :         std::unordered_set<std::string> _requiredParameters;
     193             : 
     194             :         std::unordered_map<std::string, kainjow::mustache::partial> getPartials () const;
     195             : };
     196             : 
     197             : /**
     198             :  * Singleton class containing the list of known templates for the gen command.
     199             :  */
     200          18 : class GenTemplateList
     201             : {
     202             : public:
     203             :         /**
     204             :          * @return the singleton instance of GenTemplateList
     205             :          */
     206           9 :         static GenTemplateList & getInstance ()
     207             :         {
     208           9 :                 static GenTemplateList instance; // Guaranteed to be destroyed. Instantiated on first use.
     209           9 :                 return instance;
     210             :         }
     211             : 
     212             :         /**
     213             :          * Find a template with a given name.
     214             :          *
     215             :          * @param name       the unique name of the template
     216             :          * @param parameters the map of parameters passed to the template
     217             :          *
     218             :          * @return a pointer to the template with the given name initialized with the given parameters
     219             :          * or GenTemplate::empty, if the template wasn't found
     220             :          */
     221             :         const GenTemplate * getTemplate (const std::string & name, const std::unordered_map<std::string, std::string> & parameters) const;
     222             : 
     223             : private:
     224             :         GenTemplateList ();
     225             : 
     226             :         template <class genClass>
     227             :         void addTemplate (const std::string & name);
     228             :         std::unordered_map<std::string, std::unique_ptr<GenTemplate>> _templates;
     229             : 
     230             : public:
     231             :         // public for better error messages
     232             :         GenTemplateList (GenTemplateList const &) = delete;
     233             :         void operator= (GenTemplateList const &) = delete;
     234             : };
     235             : 
     236           0 : class EmptyGenTemplate : public GenTemplate
     237             : {
     238             : public:
     239             :         /**
     240             :          * @return the singleton instance of EmptyGenTemplate
     241             :          */
     242           0 :         static EmptyGenTemplate & getInstance ()
     243             :         {
     244           0 :                 static EmptyGenTemplate instance; // Guaranteed to be destroyed. Instantiated on first use.
     245           0 :                 return instance;
     246             :         }
     247             : 
     248           0 :         bool isEmpty () const override
     249             :         {
     250           0 :                 return true;
     251             :         }
     252             : 
     253           0 :         kainjow::mustache::data getTemplateData (const std::string & outputName ELEKTRA_UNUSED, const std::string & part ELEKTRA_UNUSED,
     254             :                                                  const kdb::KeySet & ks ELEKTRA_UNUSED,
     255             :                                                  const std::string & parentKey ELEKTRA_UNUSED) const override
     256             :         {
     257           0 :                 return {};
     258             :         }
     259             : 
     260             : private:
     261           0 :         EmptyGenTemplate ()
     262           0 :         : GenTemplate ("", std::vector<std::string> (), std::vector<std::string> (), std::unordered_map<std::string, bool> ())
     263             :         {
     264           0 :         }
     265             : 
     266             : public:
     267             :         // public for better error messages
     268             :         EmptyGenTemplate (EmptyGenTemplate const &) = delete;
     269             :         void operator= (EmptyGenTemplate const &) = delete;
     270             : };
     271             : 
     272             : #endif // ELEKTRA_KDB_GEN_TEMPLATE_HPP

Generated by: LCOV version 1.13