Program Listing for File config_loader.cpp#
↰ Return to documentation for file (Src/config_loader.cpp)
module;
#include <expected>
#include <fstream>
#include <nlohmann/json.hpp>
#include <sstream>
module kataglyphis.config_loader;
namespace kataglyphis::config {
using json = nlohmann::json;
auto get_default_webrtc_config() -> WebRTCConfig
{
WebRTCConfig config;
config.stun_servers.emplace_back("stun:stun.l.google.com:19302");
return config;
}
auto parse_webrtc_config(const std::string &json_content) -> std::expected<WebRTCConfig, ConfigError>
{
if (!json::accept(json_content)) { return std::unexpected(ConfigError::ParseError); }
auto j = json::parse(json_content);
WebRTCConfig config;
auto safe_get_string = [&j](const std::string &key) -> std::expected<std::string, ConfigError> {
if (!j.contains(key) || !j[key].is_string()) { return std::unexpected(ConfigError::InvalidValue); }
return j[key].template get<std::string>();
};
auto safe_get_uint = [](const auto &obj, const std::string &key) -> std::expected<std::uint32_t, ConfigError> {
if (!obj.contains(key) || !obj[key].is_number_unsigned()) { return std::unexpected(ConfigError::InvalidValue); }
return obj[key].template get<std::uint32_t>();
};
if (j.contains("signalingServerUrl")) {
if (auto val = safe_get_string("signalingServerUrl")) {
config.signaling_server_url = *val;
} else {
return std::unexpected(val.error());
}
}
if (j.contains("reconnectionTimeoutMs")) {
if (auto val = safe_get_uint(j, "reconnectionTimeoutMs")) {
config.reconnection_timeout_ms = *val;
} else {
return std::unexpected(val.error());
}
}
if (j.contains("stunServers") && j["stunServers"].is_array()) {
for (const auto &server : j["stunServers"]) {
if (!server.is_string()) { return std::unexpected(ConfigError::InvalidValue); }
config.stun_servers.push_back(server.get<std::string>());
}
}
if (j.contains("turnServers") && j["turnServers"].is_array()) {
for (const auto &server : j["turnServers"]) {
if (!server.is_string()) { return std::unexpected(ConfigError::InvalidValue); }
config.turn_servers.push_back(server.get<std::string>());
}
}
if (j.contains("video") && j["video"].is_object()) {
const auto &video = j["video"];
if (video.contains("defaultWidth")) {
if (auto val = safe_get_uint(video, "defaultWidth")) {
config.video.default_width = *val;
} else {
return std::unexpected(val.error());
}
}
if (video.contains("defaultHeight")) {
if (auto val = safe_get_uint(video, "defaultHeight")) {
config.video.default_height = *val;
} else {
return std::unexpected(val.error());
}
}
if (video.contains("defaultFramerate")) {
if (auto val = safe_get_uint(video, "defaultFramerate")) {
config.video.default_framerate = *val;
} else {
return std::unexpected(val.error());
}
}
if (video.contains("defaultBitrateKbps")) {
if (auto val = safe_get_uint(video, "defaultBitrateKbps")) {
config.video.default_bitrate_kbps = *val;
} else {
return std::unexpected(val.error());
}
}
}
if (j.contains("texture") && j["texture"].is_object()) {
const auto &texture = j["texture"];
if (texture.contains("width")) {
if (auto val = safe_get_uint(texture, "width")) {
config.texture.width = *val;
} else {
return std::unexpected(val.error());
}
}
if (texture.contains("height")) {
if (auto val = safe_get_uint(texture, "height")) {
config.texture.height = *val;
} else {
return std::unexpected(val.error());
}
}
}
if (j.contains("android") && j["android"].is_object()) {
const auto &android = j["android"];
if (android.contains("width")) {
if (auto val = safe_get_uint(android, "width")) {
config.android.width = *val;
} else {
return std::unexpected(val.error());
}
}
if (android.contains("height")) {
if (auto val = safe_get_uint(android, "height")) {
config.android.height = *val;
} else {
return std::unexpected(val.error());
}
}
if (android.contains("fps")) {
if (auto val = safe_get_uint(android, "fps")) {
config.android.fps = *val;
} else {
return std::unexpected(val.error());
}
}
}
return config;
}
auto load_webrtc_config(const std::filesystem::path &config_path) -> std::expected<WebRTCConfig, ConfigError>
{
if (!std::filesystem::exists(config_path)) { return std::unexpected(ConfigError::FileNotFound); }
std::ifstream file(config_path);
if (!file.is_open()) { return std::unexpected(ConfigError::FileNotFound); }
std::stringstream buffer;
buffer << file.rdbuf();
return parse_webrtc_config(buffer.str());
}
}// namespace kataglyphis::config