LCOV - code coverage report
Current view: top level - src/outputs/formatters - JsonInputFileFormatter.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 122 122 100.0 %
Date: 2025-07-17 01:28:37 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "JsonInputFileFormatter.h"
      11             : #include "MooseUtils.h"
      12             : 
      13             : #include <vector>
      14             : 
      15          14 : JsonInputFileFormatter::JsonInputFileFormatter() : _spaces(2), _level(0) {}
      16             : 
      17             : std::string
      18          14 : JsonInputFileFormatter::toString(const nlohmann::json & root)
      19             : {
      20          14 :   _stream.clear();
      21          14 :   _stream.str("");
      22        1054 :   for (auto && el : root["blocks"].items())
      23         534 :     addBlock(el.key(), el.value(), true);
      24          14 :   return _stream.str();
      25             : }
      26             : 
      27             : void
      28      914807 : JsonInputFileFormatter::addLine(const std::string & line,
      29             :                                 size_t max_line_len,
      30             :                                 const std::string & comment)
      31             : {
      32      914807 :   if (line.empty() && comment.empty())
      33             :   {
      34       17167 :     _stream << "\n";
      35       51501 :     return;
      36             :   }
      37             : 
      38      897640 :   std::string indent(_level * _spaces, ' ');
      39      897640 :   auto doc = MooseUtils::trim(comment);
      40      897640 :   if (doc.empty()) // Not comment so just print out the line normally
      41             :   {
      42       34334 :     _stream << indent << line << "\n";
      43       34334 :     return;
      44             :   }
      45             : 
      46             :   // We have a comment so we need to break it up over multiple lines if necessary
      47             :   // and make sure that they all start at the same spot.
      48      863306 :   _stream << indent << line;
      49      863306 :   std::vector<std::string> elements;
      50             : 
      51             :   // if the line is empty we can just start the comment right away
      52      863306 :   int extra = 1;
      53      863306 :   if (line.empty())
      54      580720 :     extra = 0;
      55             : 
      56             :   // be careful of really long lines.
      57      863306 :   int len = 100 - max_line_len - indent.size();
      58      863306 :   if (len < 0)
      59        3136 :     len = 20;
      60             : 
      61      863306 :   MooseUtils::tokenize(doc, elements, len, " \t");
      62      863306 :   std::string first(max_line_len - line.size() + extra, ' ');
      63      863306 :   _stream << first << "# " << elements[0] << "\n";
      64      863306 :   std::string cindent(max_line_len + indent.size() + extra, ' ');
      65     1418622 :   for (size_t i = 1; i < elements.size(); ++i)
      66      555316 :     _stream << cindent << "# " << elements[i] << "\n";
      67             : 
      68      863306 :   _stream << std::flush;
      69      931974 : }
      70             : 
      71             : void
      72       16696 : JsonInputFileFormatter::addBlock(const std::string & name,
      73             :                                  const nlohmann::json & block,
      74             :                                  bool toplevel)
      75             : {
      76       16696 :   addLine("");
      77       16696 :   if (toplevel)
      78         520 :     addLine("[" + name + "]");
      79             :   else
      80       16176 :     addLine("[./" + name + "]");
      81             : 
      82       16696 :   _level++;
      83       16696 :   std::string desc = block.contains("description") ? nlohmann::to_string(block["description"]) : "";
      84       16696 :   if (!desc.empty())
      85       15548 :     addLine("", 0, desc);
      86             : 
      87       16696 :   if (block.contains("parameters"))
      88       15548 :     addParameters(block["parameters"]);
      89             : 
      90       16696 :   if (block.contains("actions"))
      91             :   {
      92             :     // there could be duplicate parameters across actions, last one wins
      93         716 :     nlohmann::json all_params;
      94         716 :     auto & actions = block["actions"];
      95        2330 :     for (auto && el : actions.items())
      96             :     {
      97         807 :       auto & params = el.value()["parameters"];
      98        6261 :       for (auto && param_el : params.items())
      99        6261 :         all_params[param_el.key()] = param_el.value();
     100         716 :     }
     101         716 :     addParameters(all_params);
     102         716 :   }
     103             : 
     104       16696 :   if (block.contains("star"))
     105         460 :     addBlock("*", block["star"]);
     106             : 
     107       16696 :   addTypes("subblock_types", block);
     108       16696 :   addTypes("types", block);
     109             : 
     110       16696 :   if (block.contains("subblocks"))
     111             :   {
     112          77 :     auto & subblocks = block["subblocks"];
     113          77 :     if (!subblocks.is_null())
     114         413 :       for (auto && el : subblocks.items())
     115         245 :         addBlock(el.key(), el.value());
     116             :   }
     117             : 
     118       16696 :   _level--;
     119       16696 :   if (toplevel)
     120         520 :     addLine("[]");
     121             :   else
     122       16176 :     addLine("[../]");
     123       16696 : }
     124             : 
     125             : void
     126       33392 : JsonInputFileFormatter::addTypes(const std::string & key, const nlohmann::json & block)
     127             : {
     128       33392 :   if (!block.contains(key))
     129       32676 :     return;
     130         716 :   auto & types = block[key];
     131         716 :   if (types.is_null())
     132         245 :     return;
     133             : 
     134         471 :   addLine("");
     135         471 :   addLine("[./<types>]");
     136         471 :   _level++;
     137       16019 :   for (auto && el : types.items())
     138       16019 :     addBlock("<" + el.key() + ">", el.value());
     139         471 :   _level--;
     140         471 :   addLine("[../]");
     141             : }
     142             : 
     143             : void
     144       16264 : JsonInputFileFormatter::addParameters(const nlohmann::json & params)
     145             : {
     146       16264 :   size_t max_name = 0;
     147      581436 :   for (auto & el : params.items())
     148      282586 :     if (el.key().size() > max_name)
     149       52352 :       max_name = el.key().size();
     150             : 
     151       16264 :   size_t max_len = 0;
     152       16264 :   std::map<std::string, std::string> lines;
     153      581436 :   for (auto && el : params.items())
     154             :   {
     155      282586 :     auto & name = el.key();
     156      282586 :     auto & param = el.value();
     157             :     auto def =
     158      282586 :         param.contains("default") ? MooseUtils::trim(nlohmann::to_string(param["default"])) : "";
     159      282586 :     if (!def.empty())
     160      190647 :       def = def.substr(1, def.size() - 2);
     161      282586 :     if (def.find(' ') != std::string::npos)
     162        5676 :       def = "'" + def + "'";
     163      282586 :     std::string indent(max_name - name.size(), ' ');
     164      282586 :     std::string required;
     165      282586 :     if (param["required"])
     166       27148 :       required = "(required)";
     167      282586 :     if (def.size() == 0 && required.size() == 0)
     168       92879 :       def = "(no_default)";
     169      282586 :     std::string l = name + indent + " = " + def + required;
     170      282586 :     if (l.size() > max_len)
     171       40532 :       max_len = l.size();
     172      282586 :     lines[name] = l;
     173      298850 :   }
     174      581436 :   for (auto & el : params.items())
     175             :   {
     176      282586 :     auto & name = el.key();
     177      282586 :     auto & param = el.value();
     178      282586 :     auto & l = lines[name];
     179      282586 :     auto desc = nlohmann::to_string(param["description"]);
     180      282586 :     addLine(l, max_len, desc);
     181             : 
     182      282586 :     const auto doc_unit = nlohmann::to_string(param["doc_unit"]);
     183      282586 :     if (!doc_unit.empty())
     184      282586 :       addLine("", max_len + 1,
     185      565172 :               "Unit: " + doc_unit); // a +1 to account for an empty line
     186             : 
     187      282586 :     const auto group = nlohmann::to_string(param["group_name"]);
     188      282586 :     if (!group.empty())
     189      282586 :       addLine("", max_len + 1,
     190      565172 :               "Group: " + group); // a +1 to account for an empty line
     191      298850 :   }
     192       16264 : }

Generated by: LCOV version 1.14