Initial public khodo snapshot
publish / publish (push) Successful in 53m2s

This commit is contained in:
khodowany
2026-09-04 19:30:11 -05:00
commit 2750dd7f3a
51 changed files with 5515 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include <modulus/config.hpp>
#include <modulus/error.hpp>
#include <modulus/json_config.hpp>
#include <modulus/log.hpp>
#include <modulus/result.hpp>
#include <modulus/source_location.hpp>
#include <modulus/types.hpp>
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include <expected>
#include <string>
#include <boost/json/value.hpp>
#include <modulus/error.hpp>
#include <modulus/log.hpp>
namespace modulus {
struct logging_config {
modulus::log_level level{modulus::log_level::INFO};
};
struct config {
modulus::logging_config logging{};
modulus::error_config errors{};
};
auto parse_logging_config(boost::json::value const& value) -> std::expected<modulus::logging_config, modulus::error>;
auto parse_error_config(boost::json::value const& value) -> std::expected<modulus::error_config, modulus::error>;
auto parse_config(boost::json::value const& value) -> std::expected<modulus::config, modulus::error>;
auto load_config(std::string const& path) -> std::expected<modulus::config, modulus::error>;
auto to_json(modulus::logging_config const& config) -> boost::json::value;
auto to_json(modulus::error_config const& config) -> boost::json::value;
auto to_json(modulus::config const& config) -> boost::json::value;
auto configure_logger(modulus::logger& logger, modulus::logging_config const& config) -> void;
auto configure(modulus::config const& config) -> void;
}
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <cstdint>
#include <string>
#include <string_view>
#include <modulus/source_location.hpp>
#include <modulus/types.hpp>
namespace modulus {
struct error_config {
std::bool_t include_category{true};
std::bool_t include_code{true};
std::bool_t include_message{true};
std::bool_t include_location{true};
};
class error {
public:
error() = default;
error(std::string category, std::int32_t code, std::string message, modulus::source_location location = modulus::source_location( __builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION()));
auto category() const noexcept -> std::string_view;
auto code() const noexcept -> std::int32_t;
auto message() const noexcept -> std::string_view;
auto location() const noexcept -> const modulus::source_location&;
auto describe(modulus::error_config const& config) const -> std::string;
auto describe() const -> std::string;
private:
std::string category_{"generic"};
std::int32_t code_{};
std::string message_{};
modulus::source_location location_{modulus::source_location::unknown()};
};
auto make_error(std::string category, std::int32_t code, std::string message, modulus::source_location location = modulus::source_location( __builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> modulus::error;
auto set_default_error_config(modulus::error_config config) -> void;
auto default_error_config() -> modulus::error_config;
}
+72
View File
@@ -0,0 +1,72 @@
#pragma once
#include <chrono>
#include <cstdint>
#include <expected>
#include <initializer_list>
#include <limits>
#include <string>
#include <string_view>
#include <boost/json/object.hpp>
#include <boost/json/value.hpp>
#include <modulus/error.hpp>
#include <modulus/types.hpp>
namespace modulus::json_config {
struct options {
std::string_view category{"modulus.config"};
std::int32_t invalid_argument_code{1};
std::int32_t not_found_code{2};
};
template <typename ENUM>
struct enum_mapping {
std::string_view name{};
ENUM value{};
};
auto invalid(modulus::json_config::options config, std::string message) -> modulus::error;
auto not_found(modulus::json_config::options config, std::string message) -> modulus::error;
auto load_value(std::string const& path, modulus::json_config::options config = {}) -> std::expected<boost::json::value, modulus::error>;
auto require_object(boost::json::value const& value, std::string_view context, modulus::json_config::options config = {}) -> std::expected<boost::json::object const*, modulus::error>;
auto reject_unknown_fields(boost::json::object const& object, std::initializer_list<std::string_view> allowed, std::string_view context, modulus::json_config::options config = {}) -> std::expected<void, modulus::error>;
auto optional_bool_field(boost::json::object const& object, std::string_view name, std::bool_t fallback, modulus::json_config::options config = {}) -> std::expected<std::bool_t, modulus::error>;
auto optional_string_field(boost::json::object const& object, std::string_view name, std::string fallback, modulus::json_config::options config = {}) -> std::expected<std::string, modulus::error>;
auto required_string_field(boost::json::object const& object, std::string_view name, std::string_view context, modulus::json_config::options config = {}) -> std::expected<std::string, modulus::error>;
auto optional_uint64_field(boost::json::object const& object, std::string_view name, std::uint64_t fallback, std::uint64_t max_value, modulus::json_config::options config = {}) -> std::expected<std::uint64_t, modulus::error>;
auto positive_uint64_field(boost::json::object const& object, std::string_view name, std::uint64_t fallback, std::uint64_t max_value, modulus::json_config::options config = {}) -> std::expected<std::uint64_t, modulus::error>;
auto optional_int32_field(boost::json::object const& object, std::string_view name, std::int32_t fallback, std::int32_t min_value, std::int32_t max_value, modulus::json_config::options config = {}) -> std::expected<std::int32_t, modulus::error>;
auto positive_milliseconds_field(boost::json::object const& object, std::string_view name, std::chrono::milliseconds fallback, std::uint64_t max_value = static_cast<std::uint64_t>(std::numeric_limits<std::int64_t>::max()), modulus::json_config::options config = {}) -> std::expected<std::chrono::milliseconds, modulus::error>;
template <typename ENUM>
auto parse_enum(std::string_view value, std::initializer_list<modulus::json_config::enum_mapping<ENUM>> mappings, std::string_view message, modulus::json_config::options config = {}) -> std::expected<ENUM, modulus::error>;
template <typename ENUM>
auto optional_enum_field(boost::json::object const& object, std::string_view name, ENUM fallback, std::initializer_list<modulus::json_config::enum_mapping<ENUM>> mappings, std::string_view message, modulus::json_config::options config = {}) -> std::expected<ENUM, modulus::error>;
}
template <typename ENUM>
auto modulus::json_config::parse_enum(std::string_view value, std::initializer_list<modulus::json_config::enum_mapping<ENUM>> mappings, std::string_view message, modulus::json_config::options config) -> std::expected<ENUM, modulus::error> {
for (auto mapping : mappings) {
if (value == mapping.name) {
return mapping.value;
}
}
return std::unexpected(modulus::json_config::invalid(config, std::string{message}));
}
template <typename ENUM>
auto modulus::json_config::optional_enum_field(boost::json::object const& object, std::string_view name, ENUM fallback, std::initializer_list<modulus::json_config::enum_mapping<ENUM>> mappings, std::string_view message, modulus::json_config::options config) -> std::expected<ENUM, modulus::error> {
auto found = object.find(name);
if (found == object.end()) {
return fallback;
}
if (!found->value().is_string()) {
return std::unexpected(modulus::json_config::invalid(config, std::string{name} + " must be a string"));
}
return modulus::json_config::parse_enum(std::string_view{found->value().as_string()}, mappings, message, config);
}
+79
View File
@@ -0,0 +1,79 @@
#pragma once
#include <cassert>
#include <chrono>
#include <cstdint>
#include <functional>
#include <mutex>
#include <string>
#include <string_view>
#include <thread>
#include <utility>
#include <modulus/source_location.hpp>
#include <modulus/types.hpp>
namespace modulus {
enum class log_level : std::int32_t {
TRACE,
DEBUG,
INFO,
WARN,
ERROR,
CRITICAL,
OFF,
};
auto to_string(modulus::log_level level) noexcept -> std::string_view;
struct log_record {
modulus::log_level level{modulus::log_level::INFO};
std::string message{};
modulus::source_location location{modulus::source_location::unknown()};
std::chrono::system_clock::time_point timestamp{std::chrono::system_clock::now()};
std::thread::id thread_id{std::this_thread::get_id()};
};
class logger {
public:
logger();
auto set_level(modulus::log_level level) -> void;
auto level() const -> modulus::log_level;
auto enabled(modulus::log_level level) const -> std::bool_t;
auto set_sink(std::function<void(const modulus::log_record&)> sink) -> void;
auto write(modulus::log_record record) const -> void;
auto log(modulus::log_level level, std::string message, modulus::source_location location = modulus::source_location( __builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) const -> void;
private:
mutable std::mutex mutex_;
mutable std::mutex sink_mutex_;
modulus::log_level level_{modulus::log_level::INFO};
std::function<void(const modulus::log_record&)> sink_{};
};
auto default_logger() -> modulus::logger&;
auto set_default_log_level(modulus::log_level level) -> void;
auto is_log_enabled(modulus::log_level level) -> std::bool_t;
auto log(modulus::log_level level, std::string message, modulus::source_location location = modulus::source_location( __builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> void;
auto log_trace(std::string message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> void;
auto log_debug(std::string message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> void;
auto log_info(std::string message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> void;
auto log_warn(std::string message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> void;
auto log_error(std::string message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> void;
auto log_critical(std::string message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> void;
template <typename MESSAGE>
auto log_lazy(modulus::log_level level, MESSAGE&& message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> void;
}
template <typename MESSAGE>
auto modulus::log_lazy(modulus::log_level level, MESSAGE&& message, modulus::source_location location) -> void {
assert(static_cast<std::int32_t>(level) >= static_cast<std::int32_t>(modulus::log_level::TRACE));
assert(static_cast<std::int32_t>(level) <= static_cast<std::int32_t>(modulus::log_level::OFF));
assert(location.file_name() != nullptr);
assert(location.function_name() != nullptr);
if (modulus::is_log_enabled(level)) {
modulus::log(level, std::string(std::forward<MESSAGE>(message)()), location);
}
}
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include <cassert>
#include <expected>
#include <type_traits>
#include <utility>
#include <modulus/error.hpp>
namespace modulus {
template <typename VALUE>
auto success(VALUE&& value) -> std::expected<std::decay_t<VALUE>, modulus::error>;
template <typename VALUE>
auto fail(modulus::error value) -> std::expected<VALUE, modulus::error>;
}
template <typename VALUE>
auto modulus::success(VALUE&& value) -> std::expected<std::decay_t<VALUE>, modulus::error> {
return std::forward<VALUE>(value);
}
template <typename VALUE>
auto modulus::fail(modulus::error value) -> std::expected<VALUE, modulus::error> {
assert(!value.category().empty());
return std::unexpected<modulus::error>(std::move(value));
}
+55
View File
@@ -0,0 +1,55 @@
#pragma once
#include <cassert>
#include <cstdint>
#include <modulus/types.hpp>
namespace modulus {
class source_location {
public:
constexpr source_location() noexcept = default;
constexpr source_location(std::char_t const* file, std::uint_least32_t line, std::char_t const* function) noexcept;
static consteval auto current(std::char_t const* file = __builtin_FILE(), std::uint_least32_t line = __builtin_LINE(), std::char_t const* function = __builtin_FUNCTION()) noexcept -> modulus::source_location;
static constexpr auto unknown() noexcept -> modulus::source_location;
constexpr auto file_name() const noexcept -> std::char_t const*;
constexpr auto line() const noexcept -> std::uint_least32_t;
constexpr auto function_name() const noexcept -> std::char_t const*;
private:
std::char_t const* file_{"<unknown>"};
std::uint_least32_t line_{};
std::char_t const* function_{"<unknown>"};
};
}
constexpr modulus::source_location::source_location(std::char_t const* file, std::uint_least32_t line, std::char_t const* function) noexcept : file_(file), line_(line), function_(function) {
assert(file != nullptr);
assert(function != nullptr);
}
consteval auto modulus::source_location::current(std::char_t const* file, std::uint_least32_t line, std::char_t const* function) noexcept -> modulus::source_location {
assert(file != nullptr);
assert(function != nullptr);
return modulus::source_location(file, line, function);
}
constexpr auto modulus::source_location::unknown() noexcept -> modulus::source_location {
return modulus::source_location();
}
constexpr auto modulus::source_location::file_name() const noexcept -> std::char_t const* {
assert(file_ != nullptr);
return file_;
}
constexpr auto modulus::source_location::line() const noexcept -> std::uint_least32_t {
assert(file_ != nullptr);
return line_;
}
constexpr auto modulus::source_location::function_name() const noexcept -> std::char_t const* {
assert(function_ != nullptr);
return function_;
}
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include <cstdint>
#if defined(__has_include)
# if __has_include(<stdfloat>)
# include <stdfloat>
# endif
#endif
namespace std {
using bool_t = decltype(true);
using char_t = decltype('x');
using uchar_t = std::uint8_t;
#if !defined(__STDCPP_FLOAT32_T__)
using float32_t = decltype(0.0F);
#endif
#if !defined(__STDCPP_FLOAT64_T__)
using float64_t = decltype(0.0);
#endif
}