#pragma once
#include <charconv>
#include <cstdint>
#include <stdexcept>
#include <string>
#include <string_view>
#include <system_error>
#include "configuration/common/parser_exception.hpp"
#include "configuration/common/raw_configuration.hpp"
namespace ddwaf {
static constexpr uint32_t max_transformers_per_address{10};
template <typename T, typename Key = std::string>
T at(const raw_configuration::map &map, const Key &key)
{
try {
return static_cast<T>(map.at(key));
} catch (const std::out_of_range &) {
throw missing_key(std::string(key));
} catch (const bad_cast &e) {
throw invalid_type(std::string(key), e);
}
}
template <typename T, typename Key>
T at(const raw_configuration::map &map, const Key &key, const T &default_)
{
try {
auto it = map.find(key);
return it == map.end() ? default_ : static_cast<T>(it->second);
} catch (const bad_cast &e) {
throw invalid_type(std::string(key), e);
}
}
inline unsigned parse_schema_version(raw_configuration::map &ruleset)
{
auto version = at<std::string_view>(ruleset, "version", {});
if (version.empty()) {
return 2;
}
auto dot_pos = version.find('.');
if (dot_pos == std::string_view::npos) {
throw parsing_error("invalid version format, expected major.minor");
}
version.remove_suffix(version.size() - dot_pos);
unsigned major;
const char *data = version.data();
const char *end = data + version.size();
if (std::from_chars(data, end, major).ec != std::errc{}) {
throw parsing_error("invalid version format, expected major.minor");
}
return major;
}
}