Program Listing for File SubscriptionRequest.cpp

Return to documentation for file (SubscriptionRequest.cpp)

#include "netio3/SubscriptionRequest.hpp"

#include <nlohmann/json.hpp>

#include "netio3/NetioIssues.hpp"

std::string netio3::SubscriptionRequest::to_json(const SubscriptionRequest& req) {
    nlohmann::json j;
    j["tag"] = req.tag;
    j["addr"] = req.addr;
    j["data_port"] = req.data_port;
    j["ack_port"] = req.ack_port;
    j["subscribe"] = static_cast<uint8_t>(req.subscribe);
    return j.dump();
}

netio3::SubscriptionRequest netio3::SubscriptionRequest::from_json(const std::string& req) {
    try {
        auto j = nlohmann::json::parse(req);

        // Validate all required fields exist before accessing them
        if (!j.contains("tag") || !j.contains("addr") || !j.contains("data_port") ||
            !j.contains("ack_port") || !j.contains("subscribe")) {
            throw SubscriptionParseError("Missing required field in subscription request", req);
        }

        // Convert with additional validation
        return SubscriptionRequest{
          .tag = j["tag"].get<std::uint64_t>(),
          .addr = j["addr"].get<std::string>(),
          .data_port = j["data_port"].get<std::uint16_t>(),
          .ack_port = j["ack_port"].get<std::uint16_t>(),
          .subscribe = static_cast<Sub>(j["subscribe"].get<uint8_t>()),
        };
    } catch (const nlohmann::json::parse_error& e) {
        throw SubscriptionParseError(std::format("Invalid JSON format: {}", e.what()), req);
    } catch (const nlohmann::json::type_error& e) {
        throw SubscriptionParseError(
          std::format("Type mismatch in subscription data: {}", e.what()), req);
    } catch (const nlohmann::json::out_of_range& e) {
        throw SubscriptionParseError(
          std::format("Missing field in subscription request: {}", e.what()), req);
    } catch (const nlohmann::json::exception& e) {
        throw SubscriptionParseError(std::format("JSON error: {}", e.what()), req);
    } catch (const std::exception& e) {
        throw SubscriptionParseError(
          std::format("Error processing subscription request: {}", e.what()), req);
    }
}

std::string netio3::SubscriptionAcknowledgement::to_json(const SubscriptionAcknowledgement& ack) {
    nlohmann::json j;
    j["tag"] = ack.tag;
    j["subscribe"] = static_cast<uint8_t>(ack.subscribe);
    return j.dump();
}

netio3::SubscriptionAcknowledgement netio3::SubscriptionAcknowledgement::from_json(const std::string& ack) {
    try {
        const auto j = nlohmann::json::parse(ack);

        // Validate all required fields exist before accessing them
        if (!j.contains("tag") || !j.contains("subscribe")) {
            throw SubscriptionParseError("Missing required field in subscription request", ack);
        }

        // Convert with additional validation
        return SubscriptionAcknowledgement{
          .tag = j["tag"].get<std::uint64_t>(),
          .subscribe = static_cast<SubscriptionRequest::Sub>(j["subscribe"].get<uint8_t>()),
        };
    } catch (const nlohmann::json::parse_error& e) {
        throw SubscriptionParseError(std::format("Invalid JSON format: {}", e.what()), ack);
    } catch (const nlohmann::json::type_error& e) {
        throw SubscriptionParseError(
          std::format("Type mismatch in subscription data: {}", e.what()), ack);
    } catch (const nlohmann::json::out_of_range& e) {
        throw SubscriptionParseError(
          std::format("Missing field in subscription acknowledgement: {}", e.what()), ack);
    } catch (const nlohmann::json::exception& e) {
        throw SubscriptionParseError(std::format("JSON error: {}", e.what()), ack);
    } catch (const std::exception& e) {
        throw SubscriptionParseError(
          std::format("Error processing subscription acknowledgement: {}", e.what()), ack);
    }
}