LCOV - code coverage report
Current view: top level - src/outputs/formatters - JsonInputFileFormatter.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 6f668f Lines: 122 122 100.0 %
Date: 2025-09-22 20:01:15 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          28 :   _stream.str("");
      22         550 :   for (auto && el : root["blocks"].items())
      23         550 :     addBlock(el.key(), el.value(), true);
      24          14 :   return _stream.str();
      25             : }
      26             : 
      27             : void
      28     1061913 : JsonInputFileFormatter::addLine(const std::string & line,
      29             :                                 size_t max_line_len,
      30             :                                 const std::string & comment)
      31             : {
      32     1061913 :   if (line.empty() && comment.empty())
      33             :   {
      34       19634 :     _stream << "\n";
      35       58902 :     return;
      36             :   }
      37             : 
      38     2084558 :   std::string indent(_level * _spaces, ' ');
      39     1042279 :   auto doc = MooseUtils::trim(comment);
      40     1042279 :   if (doc.empty()) // Not comment so just print out the line normally
      41             :   {
      42       39268 :     _stream << indent << line << "\n";
      43       39268 :     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     1003011 :   _stream << indent << line;
      49     1003011 :   std::vector<std::string> elements;
      50             : 
      51             :   // if the line is empty we can just start the comment right away
      52     1003011 :   int extra = 1;
      53     1003011 :   if (line.empty())
      54      674663 :     extra = 0;
      55             : 
      56             :   // be careful of really long lines.
      57     1003011 :   int len = 100 - max_line_len - indent.size();
      58     1003011 :   if (len < 0)
      59        3136 :     len = 20;
      60             : 
      61     2006022 :   MooseUtils::tokenize(doc, elements, len, " \t");
      62     1003011 :   std::string first(max_line_len - line.size() + extra, ' ');
      63     1003011 :   _stream << first << "# " << elements[0] << "\n";
      64     1003011 :   std::string cindent(max_line_len + indent.size() + extra, ' ');
      65     1644702 :   for (size_t i = 1; i < elements.size(); ++i)
      66      641691 :     _stream << cindent << "# " << elements[i] << "\n";
      67             : 
      68     1003011 :   _stream << std::flush;
      69     1081547 : }
      70             : 
      71             : void
      72       19147 : JsonInputFileFormatter::addBlock(const std::string & name,
      73             :                                  const nlohmann::json & block,
      74             :                                  bool toplevel)
      75             : {
      76       57441 :   addLine("");
      77       19147 :   if (toplevel)
      78        1072 :     addLine("[" + name + "]");
      79             :   else
      80       37222 :     addLine("[./" + name + "]");
      81             : 
      82       19147 :   _level++;
      83       20327 :   std::string desc = block.contains("description") ? nlohmann::to_string(block["description"]) : "";
      84       19147 :   if (!desc.empty())
      85       35934 :     addLine("", 0, desc);
      86             : 
      87       19147 :   if (block.contains("parameters"))
      88       17967 :     addParameters(block["parameters"]);
      89             : 
      90       19147 :   if (block.contains("actions"))
      91             :   {
      92             :     // there could be duplicate parameters across actions, last one wins
      93         732 :     nlohmann::json all_params;
      94         732 :     auto & actions = block["actions"];
      95        1555 :     for (auto && el : actions.items())
      96             :     {
      97         823 :       auto & params = el.value()["parameters"];
      98        6341 :       for (auto && param_el : params.items())
      99        6341 :         all_params[param_el.key()] = param_el.value();
     100         732 :     }
     101         732 :     addParameters(all_params);
     102         732 :   }
     103             : 
     104       19147 :   if (block.contains("star"))
     105        1428 :     addBlock("*", block["star"]);
     106             : 
     107       38294 :   addTypes("subblock_types", block);
     108       19147 :   addTypes("types", block);
     109             : 
     110       19147 :   if (block.contains("subblocks"))
     111             :   {
     112          77 :     auto & subblocks = block["subblocks"];
     113          77 :     if (!subblocks.is_null())
     114         245 :       for (auto && el : subblocks.items())
     115         245 :         addBlock(el.key(), el.value());
     116             :   }
     117             : 
     118       19147 :   _level--;
     119       19147 :   if (toplevel)
     120        2144 :     addLine("[]");
     121             :   else
     122       74444 :     addLine("[../]");
     123       19147 : }
     124             : 
     125             : void
     126       38294 : JsonInputFileFormatter::addTypes(const std::string & key, const nlohmann::json & block)
     127             : {
     128       38294 :   if (!block.contains(key))
     129       37562 :     return;
     130         732 :   auto & types = block[key];
     131         732 :   if (types.is_null())
     132         245 :     return;
     133             : 
     134        1948 :   addLine("");
     135        1461 :   addLine("[./<types>]");
     136         487 :   _level++;
     137       18454 :   for (auto && el : types.items())
     138       18454 :     addBlock("<" + el.key() + ">", el.value());
     139         487 :   _level--;
     140        1948 :   addLine("[../]");
     141             : }
     142             : 
     143             : void
     144       18699 : JsonInputFileFormatter::addParameters(const nlohmann::json & params)
     145             : {
     146       18699 :   size_t max_name = 0;
     147      347047 :   for (auto & el : params.items())
     148      328348 :     if (el.key().size() > max_name)
     149       62128 :       max_name = el.key().size();
     150             : 
     151       18699 :   size_t max_len = 0;
     152       18699 :   std::map<std::string, std::string> lines;
     153      347047 :   for (auto && el : params.items())
     154             :   {
     155      328348 :     auto & name = el.key();
     156      328348 :     auto & param = el.value();
     157             :     auto def =
     158      764411 :         param.contains("default") ? MooseUtils::trim(nlohmann::to_string(param["default"])) : "";
     159      328348 :     if (!def.empty())
     160      220633 :       def = def.substr(1, def.size() - 2);
     161      328348 :     if (def.find(' ') != std::string::npos)
     162        6752 :       def = "'" + def + "'";
     163      328348 :     std::string indent(max_name - name.size(), ' ');
     164      328348 :     std::string required;
     165      328348 :     if (param["required"])
     166       31316 :       required = "(required)";
     167      328348 :     if (def.size() == 0 && required.size() == 0)
     168      110527 :       def = "(no_default)";
     169      328348 :     std::string l = name + indent + " = " + def + required;
     170      328348 :     if (l.size() > max_len)
     171       45810 :       max_len = l.size();
     172      328348 :     lines[name] = l;
     173      347047 :   }
     174      347047 :   for (auto & el : params.items())
     175             :   {
     176      328348 :     auto & name = el.key();
     177      328348 :     auto & param = el.value();
     178      328348 :     auto & l = lines[name];
     179      328348 :     auto desc = nlohmann::to_string(param["description"]);
     180      328348 :     addLine(l, max_len, desc);
     181             : 
     182      328348 :     const auto doc_unit = nlohmann::to_string(param["doc_unit"]);
     183      328348 :     if (!doc_unit.empty())
     184      656696 :       addLine("", max_len + 1,
     185      656696 :               "Unit: " + doc_unit); // a +1 to account for an empty line
     186             : 
     187      328348 :     const auto group = nlohmann::to_string(param["group_name"]);
     188      328348 :     if (!group.empty())
     189      656696 :       addLine("", max_len + 1,
     190      656696 :               "Group: " + group); // a +1 to account for an empty line
     191      347047 :   }
     192       18699 : }

Generated by: LCOV version 1.14