|
|
|
@ -1,29 +1,11 @@
|
|
|
|
|
#include <config/definition.hpp>
|
|
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/// utility functions for visiting each section/definition
|
|
|
|
|
///
|
|
|
|
|
using SectionVisitor = std::function<void(const std::string&, const DefinitionMap&)>;
|
|
|
|
|
void visitSections(const SectionMap& sections, SectionVisitor visitor)
|
|
|
|
|
{
|
|
|
|
|
for (const auto& pair : sections)
|
|
|
|
|
{
|
|
|
|
|
visitor(pair.first, pair.second);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
using DefVisitor = std::function<void(const std::string&, const ConfigDefinition_ptr&)>;
|
|
|
|
|
void visitDefinitions(const DefinitionMap& defs, DefVisitor visitor)
|
|
|
|
|
{
|
|
|
|
|
for (const auto& pair : defs)
|
|
|
|
|
{
|
|
|
|
|
visitor(pair.first, pair.second);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ConfigDefinitionBase::ConfigDefinitionBase(std::string section_,
|
|
|
|
|
std::string name_,
|
|
|
|
|
bool required_,
|
|
|
|
@ -38,11 +20,16 @@ ConfigDefinitionBase::ConfigDefinitionBase(std::string section_,
|
|
|
|
|
Configuration&
|
|
|
|
|
Configuration::addDefinition(ConfigDefinition_ptr def)
|
|
|
|
|
{
|
|
|
|
|
auto sectionItr = m_definitions.find(def->section);
|
|
|
|
|
if (sectionItr == m_definitions.end())
|
|
|
|
|
m_sectionOrdering.push_back(def->section);
|
|
|
|
|
|
|
|
|
|
auto& sectionDefinitions = m_definitions[def->section];
|
|
|
|
|
if (sectionDefinitions.find(def->name) != sectionDefinitions.end())
|
|
|
|
|
throw std::invalid_argument(stringify("definition for [",
|
|
|
|
|
def->section, "]:", def->name, " already exists"));
|
|
|
|
|
|
|
|
|
|
m_definitionOrdering[def->section].push_back(def->name);
|
|
|
|
|
sectionDefinitions[def->name] = std::move(def);
|
|
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
@ -57,33 +44,11 @@ Configuration::addConfigValue(string_view section, string_view name, string_view
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ConfigDefinition_ptr&
|
|
|
|
|
Configuration::lookupDefinitionOrThrow(string_view section, string_view name) const
|
|
|
|
|
{
|
|
|
|
|
const auto sectionItr = m_definitions.find(std::string(section));
|
|
|
|
|
if (sectionItr == m_definitions.end())
|
|
|
|
|
throw std::invalid_argument(stringify("No config section ", section));
|
|
|
|
|
|
|
|
|
|
auto& sectionDefinitions = sectionItr->second;
|
|
|
|
|
const auto definitionItr = sectionDefinitions.find(std::string(name));
|
|
|
|
|
if (definitionItr == sectionDefinitions.end())
|
|
|
|
|
throw std::invalid_argument(stringify("No config item ", name, " within section ", section));
|
|
|
|
|
|
|
|
|
|
return definitionItr->second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ConfigDefinition_ptr&
|
|
|
|
|
Configuration::lookupDefinitionOrThrow(string_view section, string_view name)
|
|
|
|
|
{
|
|
|
|
|
return const_cast<ConfigDefinition_ptr&>(
|
|
|
|
|
const_cast<const Configuration*>(this)->lookupDefinitionOrThrow(section, name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Configuration::validate()
|
|
|
|
|
{
|
|
|
|
|
visitSections(m_definitions, [&](const std::string& section, const DefinitionMap& defs) {
|
|
|
|
|
visitDefinitions(defs, [&](const std::string&, const ConfigDefinition_ptr& def) {
|
|
|
|
|
visitSections([&](const std::string& section, const DefinitionMap&) {
|
|
|
|
|
visitDefinitions(section, [&](const std::string&, const ConfigDefinition_ptr& def) {
|
|
|
|
|
if (def->required and def->numFound < 1)
|
|
|
|
|
{
|
|
|
|
|
throw std::invalid_argument(stringify(
|
|
|
|
@ -99,7 +64,24 @@ Configuration::validate()
|
|
|
|
|
std::string
|
|
|
|
|
Configuration::generateDefaultConfig()
|
|
|
|
|
{
|
|
|
|
|
return "Implement me!";
|
|
|
|
|
std::ostringstream oss;
|
|
|
|
|
|
|
|
|
|
int sectionsVisited = 0;
|
|
|
|
|
|
|
|
|
|
visitSections([&](const std::string& section, const DefinitionMap&) {
|
|
|
|
|
if (sectionsVisited > 0)
|
|
|
|
|
oss << "\n";
|
|
|
|
|
|
|
|
|
|
oss << "[" << section << "]\n";
|
|
|
|
|
|
|
|
|
|
visitDefinitions(section, [&](const std::string& name, const ConfigDefinition_ptr& def) {
|
|
|
|
|
oss << name << "=" << def->defaultValueAsString() << "\n";
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
sectionsVisited++;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return oss.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string
|
|
|
|
@ -108,5 +90,48 @@ Configuration::generateOverridenConfig()
|
|
|
|
|
return "Implement me!";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ConfigDefinition_ptr&
|
|
|
|
|
Configuration::lookupDefinitionOrThrow(string_view section, string_view name) const
|
|
|
|
|
{
|
|
|
|
|
const auto sectionItr = m_definitions.find(std::string(section));
|
|
|
|
|
if (sectionItr == m_definitions.end())
|
|
|
|
|
throw std::invalid_argument(stringify("No config section ", section));
|
|
|
|
|
|
|
|
|
|
auto& sectionDefinitions = sectionItr->second;
|
|
|
|
|
const auto definitionItr = sectionDefinitions.find(std::string(name));
|
|
|
|
|
if (definitionItr == sectionDefinitions.end())
|
|
|
|
|
throw std::invalid_argument(stringify("No config item ", name, " within section ", section));
|
|
|
|
|
|
|
|
|
|
return definitionItr->second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ConfigDefinition_ptr&
|
|
|
|
|
Configuration::lookupDefinitionOrThrow(string_view section, string_view name)
|
|
|
|
|
{
|
|
|
|
|
return const_cast<ConfigDefinition_ptr&>(
|
|
|
|
|
const_cast<const Configuration*>(this)->lookupDefinitionOrThrow(section, name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Configuration::visitSections(SectionVisitor visitor) const
|
|
|
|
|
{
|
|
|
|
|
for (const std::string& section : m_sectionOrdering)
|
|
|
|
|
{
|
|
|
|
|
const auto itr = m_definitions.find(section);
|
|
|
|
|
assert(itr != m_definitions.end());
|
|
|
|
|
visitor(section, itr->second);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
void Configuration::visitDefinitions(const std::string& section, DefVisitor visitor) const
|
|
|
|
|
{
|
|
|
|
|
const auto& defs = m_definitions.at(section);
|
|
|
|
|
const auto& defOrdering = m_definitionOrdering.at(section);
|
|
|
|
|
for (const std::string& name : defOrdering)
|
|
|
|
|
{
|
|
|
|
|
const auto itr = defs.find(name);
|
|
|
|
|
assert(itr != defs.end());
|
|
|
|
|
visitor(name, itr->second);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace llarp
|
|
|
|
|
|
|
|
|
|