Files
vdm/core/generated/velox_proto.cpp
samiandClaude Opus 5 2c8f5e5d7d proto: answer CORE's freeze-blockers before 1.0.0 lands
Three corrections into 1.0.0, all of which would be major bumps once the
contract has landed. It has not: main still carries 1.0.0-draft, so these are
corrections to an unpublished version rather than changes to a released one.
ADR 0010 records that and the reasoning behind each.

B1 — TaskError.code was a bare integer, and the integer space in the contract is
JSON-RPC's, which is a different thing; TaskError's own description said so while
typing its code as one. Freeze TaskErrorCode: a string enum mirroring vdm::Error
by name and in order, all 27 failure values, verified against
core/include/vdm/util/error.hpp mechanically. ErrorCode says why a call failed;
TaskErrorCode says why a download failed, and a download fails while every RPC
succeeds. Adds TaskError.cause so max_retries_exhausted names what kept failing.

B2 — TaskSummary.segments is now explicitly the effective count in use right now,
after the per-host cap and the non-resumable demotion to 1. DownloadSpec.segments
and download.update's patch say they are the requested value.

B3 — Segment.endByte's "minimum: 0" contradicted the description's own empty-range
encoding of startByte - 1, which is -1 for the first segment of every download.
Empty ranges are no longer representable and are not needed. The range stays
CLOSED and INCLUSIVE, matching the HTTP Range header the two fields are copied
into verbatim, and that is now stated in the schema, the README, an ADR, a fixture
assertion and a conformance check. CORE asked for half-open and gets a written
notice rather than a silent schema edit. Segment state spells 'downloading' as
CORE asked, not 'receiving'.

check_contract.py now enforces segment contiguity, coverage of exactly
[0, sizeBytes-1], downloadedBytes within the range size, and the entry count
matching TaskSummary.segments. The download.get fixture claimed 8 segments while
carrying 2; it now carries 8 contiguous ones covering the whole file.

contracts/proto-answers-m1.md answers every item in core/docs/proto-requests-m1.md,
including the ones not being landed now: B2a and F2 accepted as follow-ups, F1
answered with the notify path for M1, F3 already frozen as a Checksum object
rather than a string, and D1 left for DAEMON to draft as the three-way ADR it is.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012fgjnqFCS5h5L7gZTZo3rV
2026-09-09 20:01:47 +04:00

7586 lines
343 KiB
C++

// ---------------------------------------------------------------------------
// GENERATED FILE — DO NOT EDIT.
//
// Source: contracts/schema/**
// Generator: contracts/codegen/gen_cpp.py
// Contract: v1.0.0
//
// Hand-editing this file is a merge blocker. Fix the schema and regenerate:
// python3 contracts/codegen/gen_cpp.py
// Only lane PROTO commits to contracts/.
// ---------------------------------------------------------------------------
#include "velox_proto.hpp"
#include <algorithm>
#include <regex>
namespace velox::proto {
namespace {
std::string join(std::string_view path, std::string_view key) {
std::string out(path);
out += "/";
out += key;
return out;
}
} // namespace
std::string_view to_string(ErrorCode v) noexcept {
switch (v) {
case ErrorCode::ParseError: return "ParseError";
case ErrorCode::InvalidRequest: return "InvalidRequest";
case ErrorCode::MethodNotFound: return "MethodNotFound";
case ErrorCode::InvalidParams: return "InvalidParams";
case ErrorCode::InternalError: return "InternalError";
case ErrorCode::VersionMismatch: return "VersionMismatch";
case ErrorCode::NotPaired: return "NotPaired";
case ErrorCode::TransportForbidden: return "TransportForbidden";
case ErrorCode::TaskNotFound: return "TaskNotFound";
case ErrorCode::InvalidPath: return "InvalidPath";
case ErrorCode::DiskFull: return "DiskFull";
case ErrorCode::ProbeFailed: return "ProbeFailed";
case ErrorCode::RateLimited: return "RateLimited";
}
return "";
}
std::optional<ErrorCode> errorcode_from_int(std::int32_t v) noexcept {
switch (v) {
case -32700: return ErrorCode::ParseError;
case -32600: return ErrorCode::InvalidRequest;
case -32601: return ErrorCode::MethodNotFound;
case -32602: return ErrorCode::InvalidParams;
case -32603: return ErrorCode::InternalError;
case -32001: return ErrorCode::VersionMismatch;
case -32002: return ErrorCode::NotPaired;
case -32003: return ErrorCode::TransportForbidden;
case -32010: return ErrorCode::TaskNotFound;
case -32011: return ErrorCode::InvalidPath;
case -32012: return ErrorCode::DiskFull;
case -32013: return ErrorCode::ProbeFailed;
case -32014: return ErrorCode::RateLimited;
default: return std::nullopt;
}
}
void to_json(nlohmann::json& j, const ErrorCode& v) { j = static_cast<std::int32_t>(v); }
template <> Result<ErrorCode> parse<ErrorCode>(const nlohmann::json& j, std::string_view path) {
if (!j.is_number_integer()) return std::unexpected(ParseError{std::string(path), "expected an integer"});
auto v = errorcode_from_int(j.get<std::int32_t>());
if (!v) return std::unexpected(ParseError{std::string(path), "not a contract error code"});
return *v;
}
std::string_view to_string(TaskState v) noexcept {
switch (v) {
case TaskState::New: return "new";
case TaskState::Probing: return "probing";
case TaskState::Queued: return "queued";
case TaskState::Connecting: return "connecting";
case TaskState::Downloading: return "downloading";
case TaskState::Paused: return "paused";
case TaskState::RetryWait: return "retry_wait";
case TaskState::Assembling: return "assembling";
case TaskState::Verifying: return "verifying";
case TaskState::Complete: return "complete";
case TaskState::Failed: return "failed";
case TaskState::Cancelled: return "cancelled";
}
return "";
}
Result<TaskState> parse_TaskState(std::string_view s) {
if (s == "new") return TaskState::New;
if (s == "probing") return TaskState::Probing;
if (s == "queued") return TaskState::Queued;
if (s == "connecting") return TaskState::Connecting;
if (s == "downloading") return TaskState::Downloading;
if (s == "paused") return TaskState::Paused;
if (s == "retry_wait") return TaskState::RetryWait;
if (s == "assembling") return TaskState::Assembling;
if (s == "verifying") return TaskState::Verifying;
if (s == "complete") return TaskState::Complete;
if (s == "failed") return TaskState::Failed;
if (s == "cancelled") return TaskState::Cancelled;
return std::unexpected(ParseError{"", "not a valid TaskState: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const TaskState& v) { j = to_string(v); }
template <> Result<TaskState> parse<TaskState>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_TaskState(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(BypassModifier v) noexcept {
switch (v) {
case BypassModifier::Alt: return "alt";
case BypassModifier::Ctrl: return "ctrl";
case BypassModifier::Shift: return "shift";
case BypassModifier::None: return "none";
}
return "";
}
Result<BypassModifier> parse_BypassModifier(std::string_view s) {
if (s == "alt") return BypassModifier::Alt;
if (s == "ctrl") return BypassModifier::Ctrl;
if (s == "shift") return BypassModifier::Shift;
if (s == "none") return BypassModifier::None;
return std::unexpected(ParseError{"", "not a valid BypassModifier: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const BypassModifier& v) { j = to_string(v); }
template <> Result<BypassModifier> parse<BypassModifier>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_BypassModifier(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(ChecksumAlgorithm v) noexcept {
switch (v) {
case ChecksumAlgorithm::Md5: return "md5";
case ChecksumAlgorithm::Sha1: return "sha1";
case ChecksumAlgorithm::Sha256: return "sha256";
case ChecksumAlgorithm::Sha512: return "sha512";
}
return "";
}
Result<ChecksumAlgorithm> parse_ChecksumAlgorithm(std::string_view s) {
if (s == "md5") return ChecksumAlgorithm::Md5;
if (s == "sha1") return ChecksumAlgorithm::Sha1;
if (s == "sha256") return ChecksumAlgorithm::Sha256;
if (s == "sha512") return ChecksumAlgorithm::Sha512;
return std::unexpected(ParseError{"", "not a valid ChecksumAlgorithm: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const ChecksumAlgorithm& v) { j = to_string(v); }
template <> Result<ChecksumAlgorithm> parse<ChecksumAlgorithm>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_ChecksumAlgorithm(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(StartMode v) noexcept {
switch (v) {
case StartMode::Now: return "now";
case StartMode::Later: return "later";
case StartMode::Queue: return "queue";
}
return "";
}
Result<StartMode> parse_StartMode(std::string_view s) {
if (s == "now") return StartMode::Now;
if (s == "later") return StartMode::Later;
if (s == "queue") return StartMode::Queue;
return std::unexpected(ParseError{"", "not a valid StartMode: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const StartMode& v) { j = to_string(v); }
template <> Result<StartMode> parse<StartMode>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_StartMode(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(MediaVariantContainer v) noexcept {
switch (v) {
case MediaVariantContainer::Ts: return "ts";
case MediaVariantContainer::Mp4: return "mp4";
case MediaVariantContainer::Webm: return "webm";
case MediaVariantContainer::Mkv: return "mkv";
}
return "";
}
Result<MediaVariantContainer> parse_MediaVariantContainer(std::string_view s) {
if (s == "ts") return MediaVariantContainer::Ts;
if (s == "mp4") return MediaVariantContainer::Mp4;
if (s == "webm") return MediaVariantContainer::Webm;
if (s == "mkv") return MediaVariantContainer::Mkv;
return std::unexpected(ParseError{"", "not a valid MediaVariantContainer: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const MediaVariantContainer& v) { j = to_string(v); }
template <> Result<MediaVariantContainer> parse<MediaVariantContainer>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_MediaVariantContainer(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(MediaVariantKind v) noexcept {
switch (v) {
case MediaVariantKind::Video: return "video";
case MediaVariantKind::Audio: return "audio";
case MediaVariantKind::Muxed: return "muxed";
case MediaVariantKind::Subtitle: return "subtitle";
}
return "";
}
Result<MediaVariantKind> parse_MediaVariantKind(std::string_view s) {
if (s == "video") return MediaVariantKind::Video;
if (s == "audio") return MediaVariantKind::Audio;
if (s == "muxed") return MediaVariantKind::Muxed;
if (s == "subtitle") return MediaVariantKind::Subtitle;
return std::unexpected(ParseError{"", "not a valid MediaVariantKind: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const MediaVariantKind& v) { j = to_string(v); }
template <> Result<MediaVariantKind> parse<MediaVariantKind>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_MediaVariantKind(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(QueueOnComplete v) noexcept {
switch (v) {
case QueueOnComplete::Nothing: return "nothing";
case QueueOnComplete::Exit: return "exit";
case QueueOnComplete::Shutdown: return "shutdown";
case QueueOnComplete::Hangup: return "hangup";
}
return "";
}
Result<QueueOnComplete> parse_QueueOnComplete(std::string_view s) {
if (s == "nothing") return QueueOnComplete::Nothing;
if (s == "exit") return QueueOnComplete::Exit;
if (s == "shutdown") return QueueOnComplete::Shutdown;
if (s == "hangup") return QueueOnComplete::Hangup;
return std::unexpected(ParseError{"", "not a valid QueueOnComplete: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const QueueOnComplete& v) { j = to_string(v); }
template <> Result<QueueOnComplete> parse<QueueOnComplete>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_QueueOnComplete(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(QueueState v) noexcept {
switch (v) {
case QueueState::Running: return "running";
case QueueState::Stopped: return "stopped";
}
return "";
}
Result<QueueState> parse_QueueState(std::string_view s) {
if (s == "running") return QueueState::Running;
if (s == "stopped") return QueueState::Stopped;
return std::unexpected(ParseError{"", "not a valid QueueState: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const QueueState& v) { j = to_string(v); }
template <> Result<QueueState> parse<QueueState>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_QueueState(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(ScheduleMode v) noexcept {
switch (v) {
case ScheduleMode::Once: return "once";
case ScheduleMode::Periodic: return "periodic";
}
return "";
}
Result<ScheduleMode> parse_ScheduleMode(std::string_view s) {
if (s == "once") return ScheduleMode::Once;
if (s == "periodic") return ScheduleMode::Periodic;
return std::unexpected(ParseError{"", "not a valid ScheduleMode: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const ScheduleMode& v) { j = to_string(v); }
template <> Result<ScheduleMode> parse<ScheduleMode>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_ScheduleMode(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(RuleActionCapture v) noexcept {
switch (v) {
case RuleActionCapture::Take: return "take";
case RuleActionCapture::Ignore: return "ignore";
}
return "";
}
Result<RuleActionCapture> parse_RuleActionCapture(std::string_view s) {
if (s == "take") return RuleActionCapture::Take;
if (s == "ignore") return RuleActionCapture::Ignore;
return std::unexpected(ParseError{"", "not a valid RuleActionCapture: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const RuleActionCapture& v) { j = to_string(v); }
template <> Result<RuleActionCapture> parse<RuleActionCapture>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_RuleActionCapture(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(SegmentState v) noexcept {
switch (v) {
case SegmentState::Pending: return "pending";
case SegmentState::Connecting: return "connecting";
case SegmentState::Downloading: return "downloading";
case SegmentState::Stalled: return "stalled";
case SegmentState::Complete: return "complete";
case SegmentState::Failed: return "failed";
}
return "";
}
Result<SegmentState> parse_SegmentState(std::string_view s) {
if (s == "pending") return SegmentState::Pending;
if (s == "connecting") return SegmentState::Connecting;
if (s == "downloading") return SegmentState::Downloading;
if (s == "stalled") return SegmentState::Stalled;
if (s == "complete") return SegmentState::Complete;
if (s == "failed") return SegmentState::Failed;
return std::unexpected(ParseError{"", "not a valid SegmentState: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const SegmentState& v) { j = to_string(v); }
template <> Result<SegmentState> parse<SegmentState>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_SegmentState(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(SettingKey v) noexcept {
switch (v) {
case SettingKey::GeneralLaunchOnLogin: return "general.launchOnLogin";
case SettingKey::GeneralMinimizeToTray: return "general.minimizeToTray";
case SettingKey::GeneralShowDropTarget: return "general.showDropTarget";
case SettingKey::GeneralConfirmOnExit: return "general.confirmOnExit";
case SettingKey::GeneralLanguage: return "general.language";
case SettingKey::GeneralCheckForUpdates: return "general.checkForUpdates";
case SettingKey::CaptureEnabled: return "capture.enabled";
case SettingKey::CaptureMonitoredExtensions: return "capture.monitoredExtensions";
case SettingKey::CaptureMonitoredMimeTypes: return "capture.monitoredMimeTypes";
case SettingKey::CaptureMinSizeBytes: return "capture.minSizeBytes";
case SettingKey::CaptureExcludedHosts: return "capture.excludedHosts";
case SettingKey::CaptureBypassModifier: return "capture.bypassModifier";
case SettingKey::CaptureAutoStartTypes: return "capture.autoStartTypes";
case SettingKey::SaveToDefaultDir: return "saveTo.defaultDir";
case SettingKey::SaveToTempDir: return "saveTo.tempDir";
case SettingKey::SaveToAllowedRoots: return "saveTo.allowedRoots";
case SettingKey::SaveToFileExistsPolicy: return "saveTo.fileExistsPolicy";
case SettingKey::SaveToCreateSubfolderPerSite: return "saveTo.createSubfolderPerSite";
case SettingKey::ConnectionPreset: return "connection.preset";
case SettingKey::ConnectionMaxSegmentsPerDownload: return "connection.maxSegmentsPerDownload";
case SettingKey::ConnectionBufferBytes: return "connection.bufferBytes";
case SettingKey::ConnectionMaxConcurrentDownloads: return "connection.maxConcurrentDownloads";
case SettingKey::ConnectionTimeoutSec: return "connection.timeoutSec";
case SettingKey::ConnectionMaxRetries: return "connection.maxRetries";
case SettingKey::ConnectionRetryBackoffSec: return "connection.retryBackoffSec";
case SettingKey::DownloadsSpeedLimitBps: return "downloads.speedLimitBps";
case SettingKey::DownloadsSpeedLimitEnabled: return "downloads.speedLimitEnabled";
case SettingKey::DownloadsVirusScanCommand: return "downloads.virusScanCommand";
case SettingKey::DownloadsPostDownloadCommand: return "downloads.postDownloadCommand";
case SettingKey::DownloadsDuplicatePolicy: return "downloads.duplicatePolicy";
case SettingKey::DownloadsVerifyChecksums: return "downloads.verifyChecksums";
case SettingKey::ProxyMode: return "proxy.mode";
case SettingKey::ProxyHost: return "proxy.host";
case SettingKey::ProxyPort: return "proxy.port";
case SettingKey::ProxyUsername: return "proxy.username";
case SettingKey::ProxyBypassHosts: return "proxy.bypassHosts";
case SettingKey::ProxyPacUrl: return "proxy.pacUrl";
case SettingKey::SoundsEnabled: return "sounds.enabled";
case SettingKey::SoundsOnComplete: return "sounds.onComplete";
case SettingKey::SoundsOnQueueComplete: return "sounds.onQueueComplete";
case SettingKey::SoundsOnError: return "sounds.onError";
}
return "";
}
Result<SettingKey> parse_SettingKey(std::string_view s) {
if (s == "general.launchOnLogin") return SettingKey::GeneralLaunchOnLogin;
if (s == "general.minimizeToTray") return SettingKey::GeneralMinimizeToTray;
if (s == "general.showDropTarget") return SettingKey::GeneralShowDropTarget;
if (s == "general.confirmOnExit") return SettingKey::GeneralConfirmOnExit;
if (s == "general.language") return SettingKey::GeneralLanguage;
if (s == "general.checkForUpdates") return SettingKey::GeneralCheckForUpdates;
if (s == "capture.enabled") return SettingKey::CaptureEnabled;
if (s == "capture.monitoredExtensions") return SettingKey::CaptureMonitoredExtensions;
if (s == "capture.monitoredMimeTypes") return SettingKey::CaptureMonitoredMimeTypes;
if (s == "capture.minSizeBytes") return SettingKey::CaptureMinSizeBytes;
if (s == "capture.excludedHosts") return SettingKey::CaptureExcludedHosts;
if (s == "capture.bypassModifier") return SettingKey::CaptureBypassModifier;
if (s == "capture.autoStartTypes") return SettingKey::CaptureAutoStartTypes;
if (s == "saveTo.defaultDir") return SettingKey::SaveToDefaultDir;
if (s == "saveTo.tempDir") return SettingKey::SaveToTempDir;
if (s == "saveTo.allowedRoots") return SettingKey::SaveToAllowedRoots;
if (s == "saveTo.fileExistsPolicy") return SettingKey::SaveToFileExistsPolicy;
if (s == "saveTo.createSubfolderPerSite") return SettingKey::SaveToCreateSubfolderPerSite;
if (s == "connection.preset") return SettingKey::ConnectionPreset;
if (s == "connection.maxSegmentsPerDownload") return SettingKey::ConnectionMaxSegmentsPerDownload;
if (s == "connection.bufferBytes") return SettingKey::ConnectionBufferBytes;
if (s == "connection.maxConcurrentDownloads") return SettingKey::ConnectionMaxConcurrentDownloads;
if (s == "connection.timeoutSec") return SettingKey::ConnectionTimeoutSec;
if (s == "connection.maxRetries") return SettingKey::ConnectionMaxRetries;
if (s == "connection.retryBackoffSec") return SettingKey::ConnectionRetryBackoffSec;
if (s == "downloads.speedLimitBps") return SettingKey::DownloadsSpeedLimitBps;
if (s == "downloads.speedLimitEnabled") return SettingKey::DownloadsSpeedLimitEnabled;
if (s == "downloads.virusScanCommand") return SettingKey::DownloadsVirusScanCommand;
if (s == "downloads.postDownloadCommand") return SettingKey::DownloadsPostDownloadCommand;
if (s == "downloads.duplicatePolicy") return SettingKey::DownloadsDuplicatePolicy;
if (s == "downloads.verifyChecksums") return SettingKey::DownloadsVerifyChecksums;
if (s == "proxy.mode") return SettingKey::ProxyMode;
if (s == "proxy.host") return SettingKey::ProxyHost;
if (s == "proxy.port") return SettingKey::ProxyPort;
if (s == "proxy.username") return SettingKey::ProxyUsername;
if (s == "proxy.bypassHosts") return SettingKey::ProxyBypassHosts;
if (s == "proxy.pacUrl") return SettingKey::ProxyPacUrl;
if (s == "sounds.enabled") return SettingKey::SoundsEnabled;
if (s == "sounds.onComplete") return SettingKey::SoundsOnComplete;
if (s == "sounds.onQueueComplete") return SettingKey::SoundsOnQueueComplete;
if (s == "sounds.onError") return SettingKey::SoundsOnError;
return std::unexpected(ParseError{"", "not a valid SettingKey: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const SettingKey& v) { j = to_string(v); }
template <> Result<SettingKey> parse<SettingKey>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_SettingKey(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(SettingsConnectionPreset v) noexcept {
switch (v) {
case SettingsConnectionPreset::Auto: return "auto";
case SettingsConnectionPreset::Lan: return "lan";
case SettingsConnectionPreset::Broadband: return "broadband";
case SettingsConnectionPreset::Slow: return "slow";
}
return "";
}
Result<SettingsConnectionPreset> parse_SettingsConnectionPreset(std::string_view s) {
if (s == "auto") return SettingsConnectionPreset::Auto;
if (s == "lan") return SettingsConnectionPreset::Lan;
if (s == "broadband") return SettingsConnectionPreset::Broadband;
if (s == "slow") return SettingsConnectionPreset::Slow;
return std::unexpected(ParseError{"", "not a valid SettingsConnectionPreset: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const SettingsConnectionPreset& v) { j = to_string(v); }
template <> Result<SettingsConnectionPreset> parse<SettingsConnectionPreset>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_SettingsConnectionPreset(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(SettingsDownloadsDuplicatePolicy v) noexcept {
switch (v) {
case SettingsDownloadsDuplicatePolicy::Ask: return "ask";
case SettingsDownloadsDuplicatePolicy::Skip: return "skip";
case SettingsDownloadsDuplicatePolicy::Rename: return "rename";
case SettingsDownloadsDuplicatePolicy::Redownload: return "redownload";
}
return "";
}
Result<SettingsDownloadsDuplicatePolicy> parse_SettingsDownloadsDuplicatePolicy(std::string_view s) {
if (s == "ask") return SettingsDownloadsDuplicatePolicy::Ask;
if (s == "skip") return SettingsDownloadsDuplicatePolicy::Skip;
if (s == "rename") return SettingsDownloadsDuplicatePolicy::Rename;
if (s == "redownload") return SettingsDownloadsDuplicatePolicy::Redownload;
return std::unexpected(ParseError{"", "not a valid SettingsDownloadsDuplicatePolicy: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const SettingsDownloadsDuplicatePolicy& v) { j = to_string(v); }
template <> Result<SettingsDownloadsDuplicatePolicy> parse<SettingsDownloadsDuplicatePolicy>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_SettingsDownloadsDuplicatePolicy(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(SettingsProxyMode v) noexcept {
switch (v) {
case SettingsProxyMode::System: return "system";
case SettingsProxyMode::None: return "none";
case SettingsProxyMode::Http: return "http";
case SettingsProxyMode::Https: return "https";
case SettingsProxyMode::Socks5: return "socks5";
case SettingsProxyMode::Pac: return "pac";
}
return "";
}
Result<SettingsProxyMode> parse_SettingsProxyMode(std::string_view s) {
if (s == "system") return SettingsProxyMode::System;
if (s == "none") return SettingsProxyMode::None;
if (s == "http") return SettingsProxyMode::Http;
if (s == "https") return SettingsProxyMode::Https;
if (s == "socks5") return SettingsProxyMode::Socks5;
if (s == "pac") return SettingsProxyMode::Pac;
return std::unexpected(ParseError{"", "not a valid SettingsProxyMode: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const SettingsProxyMode& v) { j = to_string(v); }
template <> Result<SettingsProxyMode> parse<SettingsProxyMode>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_SettingsProxyMode(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(SettingsSaveToFileExistsPolicy v) noexcept {
switch (v) {
case SettingsSaveToFileExistsPolicy::Ask: return "ask";
case SettingsSaveToFileExistsPolicy::Rename: return "rename";
case SettingsSaveToFileExistsPolicy::Overwrite: return "overwrite";
case SettingsSaveToFileExistsPolicy::Resume: return "resume";
}
return "";
}
Result<SettingsSaveToFileExistsPolicy> parse_SettingsSaveToFileExistsPolicy(std::string_view s) {
if (s == "ask") return SettingsSaveToFileExistsPolicy::Ask;
if (s == "rename") return SettingsSaveToFileExistsPolicy::Rename;
if (s == "overwrite") return SettingsSaveToFileExistsPolicy::Overwrite;
if (s == "resume") return SettingsSaveToFileExistsPolicy::Resume;
return std::unexpected(ParseError{"", "not a valid SettingsSaveToFileExistsPolicy: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const SettingsSaveToFileExistsPolicy& v) { j = to_string(v); }
template <> Result<SettingsSaveToFileExistsPolicy> parse<SettingsSaveToFileExistsPolicy>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_SettingsSaveToFileExistsPolicy(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(TaskErrorCode v) noexcept {
switch (v) {
case TaskErrorCode::Canceled: return "canceled";
case TaskErrorCode::ResolveFailed: return "resolve_failed";
case TaskErrorCode::ConnectFailed: return "connect_failed";
case TaskErrorCode::TlsFailed: return "tls_failed";
case TaskErrorCode::ConnectionReset: return "connection_reset";
case TaskErrorCode::Timeout: return "timeout";
case TaskErrorCode::TooManyRedirects: return "too_many_redirects";
case TaskErrorCode::HttpClientError: return "http_client_error";
case TaskErrorCode::HttpServerError: return "http_server_error";
case TaskErrorCode::AuthRequired: return "auth_required";
case TaskErrorCode::Forbidden: return "forbidden";
case TaskErrorCode::NotFound: return "not_found";
case TaskErrorCode::RangeNotSatisfiable: return "range_not_satisfiable";
case TaskErrorCode::Gone: return "gone";
case TaskErrorCode::ServerFileChanged: return "server_file_changed";
case TaskErrorCode::ContentLengthMismatch: return "content_length_mismatch";
case TaskErrorCode::ChecksumMismatch: return "checksum_mismatch";
case TaskErrorCode::DiskFull: return "disk_full";
case TaskErrorCode::IoError: return "io_error";
case TaskErrorCode::PathRejected: return "path_rejected";
case TaskErrorCode::PermissionDenied: return "permission_denied";
case TaskErrorCode::MetaCorrupt: return "meta_corrupt";
case TaskErrorCode::MetaVersionUnsupported: return "meta_version_unsupported";
case TaskErrorCode::ProbeFailed: return "probe_failed";
case TaskErrorCode::UnsupportedUrlScheme: return "unsupported_url_scheme";
case TaskErrorCode::MaxRetriesExhausted: return "max_retries_exhausted";
case TaskErrorCode::Internal: return "internal";
}
return "";
}
Result<TaskErrorCode> parse_TaskErrorCode(std::string_view s) {
if (s == "canceled") return TaskErrorCode::Canceled;
if (s == "resolve_failed") return TaskErrorCode::ResolveFailed;
if (s == "connect_failed") return TaskErrorCode::ConnectFailed;
if (s == "tls_failed") return TaskErrorCode::TlsFailed;
if (s == "connection_reset") return TaskErrorCode::ConnectionReset;
if (s == "timeout") return TaskErrorCode::Timeout;
if (s == "too_many_redirects") return TaskErrorCode::TooManyRedirects;
if (s == "http_client_error") return TaskErrorCode::HttpClientError;
if (s == "http_server_error") return TaskErrorCode::HttpServerError;
if (s == "auth_required") return TaskErrorCode::AuthRequired;
if (s == "forbidden") return TaskErrorCode::Forbidden;
if (s == "not_found") return TaskErrorCode::NotFound;
if (s == "range_not_satisfiable") return TaskErrorCode::RangeNotSatisfiable;
if (s == "gone") return TaskErrorCode::Gone;
if (s == "server_file_changed") return TaskErrorCode::ServerFileChanged;
if (s == "content_length_mismatch") return TaskErrorCode::ContentLengthMismatch;
if (s == "checksum_mismatch") return TaskErrorCode::ChecksumMismatch;
if (s == "disk_full") return TaskErrorCode::DiskFull;
if (s == "io_error") return TaskErrorCode::IoError;
if (s == "path_rejected") return TaskErrorCode::PathRejected;
if (s == "permission_denied") return TaskErrorCode::PermissionDenied;
if (s == "meta_corrupt") return TaskErrorCode::MetaCorrupt;
if (s == "meta_version_unsupported") return TaskErrorCode::MetaVersionUnsupported;
if (s == "probe_failed") return TaskErrorCode::ProbeFailed;
if (s == "unsupported_url_scheme") return TaskErrorCode::UnsupportedUrlScheme;
if (s == "max_retries_exhausted") return TaskErrorCode::MaxRetriesExhausted;
if (s == "internal") return TaskErrorCode::Internal;
return std::unexpected(ParseError{"", "not a valid TaskErrorCode: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const TaskErrorCode& v) { j = to_string(v); }
template <> Result<TaskErrorCode> parse<TaskErrorCode>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_TaskErrorCode(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(TaskSortDirection v) noexcept {
switch (v) {
case TaskSortDirection::Asc: return "asc";
case TaskSortDirection::Desc: return "desc";
}
return "";
}
Result<TaskSortDirection> parse_TaskSortDirection(std::string_view s) {
if (s == "asc") return TaskSortDirection::Asc;
if (s == "desc") return TaskSortDirection::Desc;
return std::unexpected(ParseError{"", "not a valid TaskSortDirection: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const TaskSortDirection& v) { j = to_string(v); }
template <> Result<TaskSortDirection> parse<TaskSortDirection>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_TaskSortDirection(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(TaskSortField v) noexcept {
switch (v) {
case TaskSortField::Filename: return "filename";
case TaskSortField::SizeBytes: return "sizeBytes";
case TaskSortField::State: return "state";
case TaskSortField::EtaSeconds: return "etaSeconds";
case TaskSortField::SpeedBps: return "speedBps";
case TaskSortField::LastTryAt: return "lastTryAt";
case TaskSortField::CreatedAt: return "createdAt";
case TaskSortField::QueuePosition: return "queuePosition";
case TaskSortField::Description: return "description";
}
return "";
}
Result<TaskSortField> parse_TaskSortField(std::string_view s) {
if (s == "filename") return TaskSortField::Filename;
if (s == "sizeBytes") return TaskSortField::SizeBytes;
if (s == "state") return TaskSortField::State;
if (s == "etaSeconds") return TaskSortField::EtaSeconds;
if (s == "speedBps") return TaskSortField::SpeedBps;
if (s == "lastTryAt") return TaskSortField::LastTryAt;
if (s == "createdAt") return TaskSortField::CreatedAt;
if (s == "queuePosition") return TaskSortField::QueuePosition;
if (s == "description") return TaskSortField::Description;
return std::unexpected(ParseError{"", "not a valid TaskSortField: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const TaskSortField& v) { j = to_string(v); }
template <> Result<TaskSortField> parse<TaskSortField>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_TaskSortField(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(CaptureOfferParamsMethod v) noexcept {
switch (v) {
case CaptureOfferParamsMethod::GET: return "GET";
case CaptureOfferParamsMethod::POST: return "POST";
}
return "";
}
Result<CaptureOfferParamsMethod> parse_CaptureOfferParamsMethod(std::string_view s) {
if (s == "GET") return CaptureOfferParamsMethod::GET;
if (s == "POST") return CaptureOfferParamsMethod::POST;
return std::unexpected(ParseError{"", "not a valid CaptureOfferParamsMethod: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const CaptureOfferParamsMethod& v) { j = to_string(v); }
template <> Result<CaptureOfferParamsMethod> parse<CaptureOfferParamsMethod>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_CaptureOfferParamsMethod(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(CaptureOfferResultAction v) noexcept {
switch (v) {
case CaptureOfferResultAction::Take: return "take";
case CaptureOfferResultAction::Ignore: return "ignore";
}
return "";
}
Result<CaptureOfferResultAction> parse_CaptureOfferResultAction(std::string_view s) {
if (s == "take") return CaptureOfferResultAction::Take;
if (s == "ignore") return CaptureOfferResultAction::Ignore;
return std::unexpected(ParseError{"", "not a valid CaptureOfferResultAction: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const CaptureOfferResultAction& v) { j = to_string(v); }
template <> Result<CaptureOfferResultAction> parse<CaptureOfferResultAction>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_CaptureOfferResultAction(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(CaptureOfferResultReason v) noexcept {
switch (v) {
case CaptureOfferResultReason::ExcludedHost: return "excluded_host";
case CaptureOfferResultReason::TypeNotMonitored: return "type_not_monitored";
case CaptureOfferResultReason::BelowMinSize: return "below_min_size";
case CaptureOfferResultReason::Duplicate: return "duplicate";
case CaptureOfferResultReason::CaptureDisabled: return "capture_disabled";
case CaptureOfferResultReason::UserDeclined: return "user_declined";
case CaptureOfferResultReason::RuleIgnore: return "rule_ignore";
}
return "";
}
Result<CaptureOfferResultReason> parse_CaptureOfferResultReason(std::string_view s) {
if (s == "excluded_host") return CaptureOfferResultReason::ExcludedHost;
if (s == "type_not_monitored") return CaptureOfferResultReason::TypeNotMonitored;
if (s == "below_min_size") return CaptureOfferResultReason::BelowMinSize;
if (s == "duplicate") return CaptureOfferResultReason::Duplicate;
if (s == "capture_disabled") return CaptureOfferResultReason::CaptureDisabled;
if (s == "user_declined") return CaptureOfferResultReason::UserDeclined;
if (s == "rule_ignore") return CaptureOfferResultReason::RuleIgnore;
return std::unexpected(ParseError{"", "not a valid CaptureOfferResultReason: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const CaptureOfferResultReason& v) { j = to_string(v); }
template <> Result<CaptureOfferResultReason> parse<CaptureOfferResultReason>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_CaptureOfferResultReason(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(GrabberStatusResultState v) noexcept {
switch (v) {
case GrabberStatusResultState::Crawling: return "crawling";
case GrabberStatusResultState::Done: return "done";
case GrabberStatusResultState::Failed: return "failed";
case GrabberStatusResultState::Cancelled: return "cancelled";
}
return "";
}
Result<GrabberStatusResultState> parse_GrabberStatusResultState(std::string_view s) {
if (s == "crawling") return GrabberStatusResultState::Crawling;
if (s == "done") return GrabberStatusResultState::Done;
if (s == "failed") return GrabberStatusResultState::Failed;
if (s == "cancelled") return GrabberStatusResultState::Cancelled;
return std::unexpected(ParseError{"", "not a valid GrabberStatusResultState: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const GrabberStatusResultState& v) { j = to_string(v); }
template <> Result<GrabberStatusResultState> parse<GrabberStatusResultState>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_GrabberStatusResultState(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(MediaListVariantsResultManifestType v) noexcept {
switch (v) {
case MediaListVariantsResultManifestType::Hls: return "hls";
case MediaListVariantsResultManifestType::Dash: return "dash";
}
return "";
}
Result<MediaListVariantsResultManifestType> parse_MediaListVariantsResultManifestType(std::string_view s) {
if (s == "hls") return MediaListVariantsResultManifestType::Hls;
if (s == "dash") return MediaListVariantsResultManifestType::Dash;
return std::unexpected(ParseError{"", "not a valid MediaListVariantsResultManifestType: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const MediaListVariantsResultManifestType& v) { j = to_string(v); }
template <> Result<MediaListVariantsResultManifestType> parse<MediaListVariantsResultManifestType>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_MediaListVariantsResultManifestType(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(SessionHelloParamsClientType v) noexcept {
switch (v) {
case SessionHelloParamsClientType::Gui: return "gui";
case SessionHelloParamsClientType::Cli: return "cli";
case SessionHelloParamsClientType::Extension: return "extension";
case SessionHelloParamsClientType::Nmhost: return "nmhost";
case SessionHelloParamsClientType::Test: return "test";
}
return "";
}
Result<SessionHelloParamsClientType> parse_SessionHelloParamsClientType(std::string_view s) {
if (s == "gui") return SessionHelloParamsClientType::Gui;
if (s == "cli") return SessionHelloParamsClientType::Cli;
if (s == "extension") return SessionHelloParamsClientType::Extension;
if (s == "nmhost") return SessionHelloParamsClientType::Nmhost;
if (s == "test") return SessionHelloParamsClientType::Test;
return std::unexpected(ParseError{"", "not a valid SessionHelloParamsClientType: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const SessionHelloParamsClientType& v) { j = to_string(v); }
template <> Result<SessionHelloParamsClientType> parse<SessionHelloParamsClientType>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_SessionHelloParamsClientType(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(SessionHelloResultTransport v) noexcept {
switch (v) {
case SessionHelloResultTransport::Uds: return "uds";
case SessionHelloResultTransport::Ws: return "ws";
}
return "";
}
Result<SessionHelloResultTransport> parse_SessionHelloResultTransport(std::string_view s) {
if (s == "uds") return SessionHelloResultTransport::Uds;
if (s == "ws") return SessionHelloResultTransport::Ws;
return std::unexpected(ParseError{"", "not a valid SessionHelloResultTransport: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const SessionHelloResultTransport& v) { j = to_string(v); }
template <> Result<SessionHelloResultTransport> parse<SessionHelloResultTransport>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_SessionHelloResultTransport(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(SessionSubscribeParamsEventsItem v) noexcept {
switch (v) {
case SessionSubscribeParamsEventsItem::EventTaskAdded: return "event.task.added";
case SessionSubscribeParamsEventsItem::EventTaskRemoved: return "event.task.removed";
case SessionSubscribeParamsEventsItem::EventTaskState: return "event.task.state";
case SessionSubscribeParamsEventsItem::EventTaskProgress: return "event.task.progress";
case SessionSubscribeParamsEventsItem::EventSpeedGlobal: return "event.speed.global";
case SessionSubscribeParamsEventsItem::EventAuthRequired: return "event.auth.required";
case SessionSubscribeParamsEventsItem::EventNotify: return "event.notify";
case SessionSubscribeParamsEventsItem::EventSettingsChanged: return "event.settings.changed";
case SessionSubscribeParamsEventsItem::EventGrabberProgress: return "event.grabber.progress";
}
return "";
}
Result<SessionSubscribeParamsEventsItem> parse_SessionSubscribeParamsEventsItem(std::string_view s) {
if (s == "event.task.added") return SessionSubscribeParamsEventsItem::EventTaskAdded;
if (s == "event.task.removed") return SessionSubscribeParamsEventsItem::EventTaskRemoved;
if (s == "event.task.state") return SessionSubscribeParamsEventsItem::EventTaskState;
if (s == "event.task.progress") return SessionSubscribeParamsEventsItem::EventTaskProgress;
if (s == "event.speed.global") return SessionSubscribeParamsEventsItem::EventSpeedGlobal;
if (s == "event.auth.required") return SessionSubscribeParamsEventsItem::EventAuthRequired;
if (s == "event.notify") return SessionSubscribeParamsEventsItem::EventNotify;
if (s == "event.settings.changed") return SessionSubscribeParamsEventsItem::EventSettingsChanged;
if (s == "event.grabber.progress") return SessionSubscribeParamsEventsItem::EventGrabberProgress;
return std::unexpected(ParseError{"", "not a valid SessionSubscribeParamsEventsItem: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const SessionSubscribeParamsEventsItem& v) { j = to_string(v); }
template <> Result<SessionSubscribeParamsEventsItem> parse<SessionSubscribeParamsEventsItem>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_SessionSubscribeParamsEventsItem(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(AuthRequiredEventScheme v) noexcept {
switch (v) {
case AuthRequiredEventScheme::Basic: return "basic";
case AuthRequiredEventScheme::Digest: return "digest";
case AuthRequiredEventScheme::Ntlm: return "ntlm";
case AuthRequiredEventScheme::Negotiate: return "negotiate";
case AuthRequiredEventScheme::Proxy: return "proxy";
}
return "";
}
Result<AuthRequiredEventScheme> parse_AuthRequiredEventScheme(std::string_view s) {
if (s == "basic") return AuthRequiredEventScheme::Basic;
if (s == "digest") return AuthRequiredEventScheme::Digest;
if (s == "ntlm") return AuthRequiredEventScheme::Ntlm;
if (s == "negotiate") return AuthRequiredEventScheme::Negotiate;
if (s == "proxy") return AuthRequiredEventScheme::Proxy;
return std::unexpected(ParseError{"", "not a valid AuthRequiredEventScheme: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const AuthRequiredEventScheme& v) { j = to_string(v); }
template <> Result<AuthRequiredEventScheme> parse<AuthRequiredEventScheme>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_AuthRequiredEventScheme(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(NotifyEventLevel v) noexcept {
switch (v) {
case NotifyEventLevel::Info: return "info";
case NotifyEventLevel::Success: return "success";
case NotifyEventLevel::Warning: return "warning";
case NotifyEventLevel::Error: return "error";
}
return "";
}
Result<NotifyEventLevel> parse_NotifyEventLevel(std::string_view s) {
if (s == "info") return NotifyEventLevel::Info;
if (s == "success") return NotifyEventLevel::Success;
if (s == "warning") return NotifyEventLevel::Warning;
if (s == "error") return NotifyEventLevel::Error;
return std::unexpected(ParseError{"", "not a valid NotifyEventLevel: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const NotifyEventLevel& v) { j = to_string(v); }
template <> Result<NotifyEventLevel> parse<NotifyEventLevel>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_NotifyEventLevel(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
std::string_view to_string(NotifyEventSound v) noexcept {
switch (v) {
case NotifyEventSound::Complete: return "complete";
case NotifyEventSound::QueueComplete: return "queueComplete";
case NotifyEventSound::Error: return "error";
}
return "";
}
Result<NotifyEventSound> parse_NotifyEventSound(std::string_view s) {
if (s == "complete") return NotifyEventSound::Complete;
if (s == "queueComplete") return NotifyEventSound::QueueComplete;
if (s == "error") return NotifyEventSound::Error;
return std::unexpected(ParseError{"", "not a valid NotifyEventSound: '" + std::string(s) + "'"});
}
void to_json(nlohmann::json& j, const NotifyEventSound& v) { j = to_string(v); }
template <> Result<NotifyEventSound> parse<NotifyEventSound>(const nlohmann::json& j, std::string_view path) {
if (!j.is_string()) return std::unexpected(ParseError{std::string(path), "expected a string"});
auto r = parse_NotifyEventSound(j.get_ref<const std::string&>());
if (!r) return std::unexpected(ParseError{std::string(path), r.error().message});
return *r;
}
template <> Result<Headers> parse<Headers>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
std::map<std::string, std::string> out;
for (const auto& [mk, mv] : j.items()) {
const std::string mp = join(path, mk);
if (!mv.is_string()) return std::unexpected(ParseError{std::string(mp), "expected a string"});
auto out_e = mv.get<std::string>();
out.emplace(mk, std::move(out_e));
}
return out;
}
void to_json(nlohmann::json& j, const BulkTaskResultFailedItem& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["code"] = v.code;
j["message"] = v.message;
}
template <> Result<BulkTaskResultFailedItem> parse<BulkTaskResultFailedItem>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
BulkTaskResultFailedItem out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "code");
const auto it = j.find("code");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<ErrorCode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.code = std::move(val);
}
{
const std::string fp = join(path, "message");
const auto it = j.find("message");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.message = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const BulkTaskResultUpdatedItem& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["state"] = v.state;
j["changed"] = v.changed;
}
template <> Result<BulkTaskResultUpdatedItem> parse<BulkTaskResultUpdatedItem>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
BulkTaskResultUpdatedItem out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "state");
const auto it = j.find("state");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskState>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.state = std::move(val);
}
{
const std::string fp = join(path, "changed");
const auto it = j.find("changed");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.changed = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const BulkTaskResult& v) {
j = nlohmann::json::object();
j["updated"] = v.updated;
j["failed"] = v.failed;
}
template <> Result<BulkTaskResult> parse<BulkTaskResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
BulkTaskResult out;
{
const std::string fp = join(path, "updated");
const auto it = j.find("updated");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<BulkTaskResultUpdatedItem> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<BulkTaskResultUpdatedItem>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.updated = std::move(val);
}
{
const std::string fp = join(path, "failed");
const auto it = j.find("failed");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<BulkTaskResultFailedItem> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<BulkTaskResultFailedItem>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.failed = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const CaptureRules& v) {
j = nlohmann::json::object();
j["enabled"] = v.enabled;
j["monitoredExtensions"] = v.monitoredExtensions;
j["monitoredMimeTypes"] = v.monitoredMimeTypes;
j["minSizeBytes"] = v.minSizeBytes;
j["excludedHosts"] = v.excludedHosts;
if (v.bypassModifier.has_value()) j["bypassModifier"] = *v.bypassModifier;
j["rulesVersion"] = v.rulesVersion;
}
template <> Result<CaptureRules> parse<CaptureRules>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
CaptureRules out;
{
const std::string fp = join(path, "enabled");
const auto it = j.find("enabled");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.enabled = std::move(val);
}
{
const std::string fp = join(path, "monitoredExtensions");
const auto it = j.find("monitoredExtensions");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.monitoredExtensions = std::move(val);
}
{
const std::string fp = join(path, "monitoredMimeTypes");
const auto it = j.find("monitoredMimeTypes");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.monitoredMimeTypes = std::move(val);
}
{
const std::string fp = join(path, "minSizeBytes");
const auto it = j.find("minSizeBytes");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.minSizeBytes = std::move(val);
}
{
const std::string fp = join(path, "excludedHosts");
const auto it = j.find("excludedHosts");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.excludedHosts = std::move(val);
}
{
const std::string fp = join(path, "bypassModifier");
const auto it = j.find("bypassModifier");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<BypassModifier>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.bypassModifier = std::move(val);
}
}
{
const std::string fp = join(path, "rulesVersion");
const auto it = j.find("rulesVersion");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.rulesVersion = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const Category& v) {
j = nlohmann::json::object();
j["categoryId"] = v.categoryId;
j["name"] = v.name;
j["saveDir"] = v.saveDir;
j["extensions"] = v.extensions;
if (v.mimeTypes.has_value()) j["mimeTypes"] = *v.mimeTypes;
j["builtin"] = v.builtin;
if (v.sortOrder.has_value()) j["sortOrder"] = *v.sortOrder;
}
template <> Result<Category> parse<Category>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
Category out;
{
const std::string fp = join(path, "categoryId");
const auto it = j.find("categoryId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.categoryId = std::move(val);
}
{
const std::string fp = join(path, "name");
const auto it = j.find("name");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 64u) return std::unexpected(ParseError{std::string(fp), "value is longer than 64 characters"});
out.name = std::move(val);
}
{
const std::string fp = join(path, "saveDir");
const auto it = j.find("saveDir");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.saveDir = std::move(val);
}
{
const std::string fp = join(path, "extensions");
const auto it = j.find("extensions");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
{
static const std::regex re("^[A-Za-z0-9][A-Za-z0-9+._-]*$", std::regex::ECMAScript);
if (!std::regex_match(val_e, re)) return std::unexpected(ParseError{std::string(ip), "value does not match the required pattern"});
}
val.push_back(std::move(val_e));
}
out.extensions = std::move(val);
}
{
const std::string fp = join(path, "mimeTypes");
const auto it = j.find("mimeTypes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.mimeTypes = std::move(val);
}
}
{
const std::string fp = join(path, "builtin");
const auto it = j.find("builtin");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.builtin = std::move(val);
}
{
const std::string fp = join(path, "sortOrder");
const auto it = j.find("sortOrder");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.sortOrder = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const Checksum& v) {
j = nlohmann::json::object();
j["algorithm"] = v.algorithm;
j["value"] = v.value;
}
template <> Result<Checksum> parse<Checksum>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
Checksum out;
{
const std::string fp = join(path, "algorithm");
const auto it = j.find("algorithm");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<ChecksumAlgorithm>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.algorithm = std::move(val);
}
{
const std::string fp = join(path, "value");
const auto it = j.find("value");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
{
static const std::regex re("^[0-9a-fA-F]{32,128}$", std::regex::ECMAScript);
if (!std::regex_match(val, re)) return std::unexpected(ParseError{std::string(fp), "value does not match the required pattern"});
}
out.value = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const Cookie& v) {
j = nlohmann::json::object();
j["name"] = v.name;
j["value"] = v.value;
if (v.domain.has_value()) j["domain"] = *v.domain;
if (v.path.has_value()) j["path"] = *v.path;
if (v.secure.has_value()) j["secure"] = *v.secure;
if (v.httpOnly.has_value()) j["httpOnly"] = *v.httpOnly;
}
template <> Result<Cookie> parse<Cookie>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
Cookie out;
{
const std::string fp = join(path, "name");
const auto it = j.find("name");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.name = std::move(val);
}
{
const std::string fp = join(path, "value");
const auto it = j.find("value");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.value = std::move(val);
}
{
const std::string fp = join(path, "domain");
const auto it = j.find("domain");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.domain = std::move(val);
}
}
{
const std::string fp = join(path, "path");
const auto it = j.find("path");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.path = std::move(val);
}
}
{
const std::string fp = join(path, "secure");
const auto it = j.find("secure");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.secure = std::move(val);
}
}
{
const std::string fp = join(path, "httpOnly");
const auto it = j.find("httpOnly");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.httpOnly = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const DownloadSpec& v) {
j = nlohmann::json::object();
j["url"] = v.url;
if (v.headers.has_value()) j["headers"] = *v.headers;
if (v.cookies.has_value()) j["cookies"] = *v.cookies;
if (v.referrer.has_value()) j["referrer"] = *v.referrer;
if (v.userAgent.has_value()) j["userAgent"] = *v.userAgent;
if (v.filename.has_value()) j["filename"] = *v.filename;
if (v.saveDir.has_value()) j["saveDir"] = *v.saveDir;
if (v.categoryId.has_value()) j["categoryId"] = *v.categoryId;
if (v.queueId.has_value()) j["queueId"] = *v.queueId;
if (v.segments.has_value()) j["segments"] = *v.segments;
if (v.bufferBytes.has_value()) j["bufferBytes"] = *v.bufferBytes;
if (v.startMode.has_value()) j["startMode"] = *v.startMode;
if (v.description.has_value()) j["description"] = *v.description;
if (v.checksum.has_value()) j["checksum"] = *v.checksum;
}
template <> Result<DownloadSpec> parse<DownloadSpec>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadSpec out;
{
const std::string fp = join(path, "url");
const auto it = j.find("url");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.url = std::move(val);
}
{
const std::string fp = join(path, "headers");
const auto it = j.find("headers");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Headers>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.headers = std::move(val);
}
}
{
const std::string fp = join(path, "cookies");
const auto it = j.find("cookies");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Cookie> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Cookie>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.cookies = std::move(val);
}
}
{
const std::string fp = join(path, "referrer");
const auto it = j.find("referrer");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.referrer = std::move(val);
}
}
{
const std::string fp = join(path, "userAgent");
const auto it = j.find("userAgent");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.userAgent = std::move(val);
}
}
{
const std::string fp = join(path, "filename");
const auto it = j.find("filename");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 255u) return std::unexpected(ParseError{std::string(fp), "value is longer than 255 characters"});
out.filename = std::move(val);
}
}
{
const std::string fp = join(path, "saveDir");
const auto it = j.find("saveDir");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.saveDir = std::move(val);
}
}
{
const std::string fp = join(path, "categoryId");
const auto it = j.find("categoryId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.categoryId = std::move(val);
}
}
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
}
{
const std::string fp = join(path, "segments");
const auto it = j.find("segments");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 32) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 32"});
out.segments = std::move(val);
}
}
{
const std::string fp = join(path, "bufferBytes");
const auto it = j.find("bufferBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 4096) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 4096"});
if (val > 8388608) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 8388608"});
out.bufferBytes = std::move(val);
}
}
{
const std::string fp = join(path, "startMode");
const auto it = j.find("startMode");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<StartMode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.startMode = std::move(val);
}
}
{
const std::string fp = join(path, "description");
const auto it = j.find("description");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 1024u) return std::unexpected(ParseError{std::string(fp), "value is longer than 1024 characters"});
out.description = std::move(val);
}
}
{
const std::string fp = join(path, "checksum");
const auto it = j.find("checksum");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Checksum>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.checksum = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const GrabberFile& v) {
j = nlohmann::json::object();
j["fileId"] = v.fileId;
j["url"] = v.url;
if (v.filename.has_value()) j["filename"] = *v.filename;
if (v.sizeBytes.has_value()) j["sizeBytes"] = *v.sizeBytes;
if (v.contentType.has_value()) j["contentType"] = *v.contentType;
j["depth"] = v.depth;
if (v.foundOn.has_value()) j["foundOn"] = *v.foundOn;
}
template <> Result<GrabberFile> parse<GrabberFile>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
GrabberFile out;
{
const std::string fp = join(path, "fileId");
const auto it = j.find("fileId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.fileId = std::move(val);
}
{
const std::string fp = join(path, "url");
const auto it = j.find("url");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.url = std::move(val);
}
{
const std::string fp = join(path, "filename");
const auto it = j.find("filename");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.filename = std::move(val);
}
}
{
const std::string fp = join(path, "sizeBytes");
const auto it = j.find("sizeBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.sizeBytes = std::move(val);
}
}
{
const std::string fp = join(path, "contentType");
const auto it = j.find("contentType");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.contentType = std::move(val);
}
}
{
const std::string fp = join(path, "depth");
const auto it = j.find("depth");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.depth = std::move(val);
}
{
const std::string fp = join(path, "foundOn");
const auto it = j.find("foundOn");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.foundOn = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const Limiter& v) {
j = nlohmann::json::object();
j["enabled"] = v.enabled;
j["globalBps"] = v.globalBps;
if (v.applyToRunning.has_value()) j["applyToRunning"] = *v.applyToRunning;
}
template <> Result<Limiter> parse<Limiter>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
Limiter out;
{
const std::string fp = join(path, "enabled");
const auto it = j.find("enabled");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.enabled = std::move(val);
}
{
const std::string fp = join(path, "globalBps");
const auto it = j.find("globalBps");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.globalBps = std::move(val);
}
{
const std::string fp = join(path, "applyToRunning");
const auto it = j.find("applyToRunning");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.applyToRunning = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const MediaVariant& v) {
j = nlohmann::json::object();
j["variantId"] = v.variantId;
j["kind"] = v.kind;
if (v.resolution.has_value()) j["resolution"] = *v.resolution;
if (v.bitrateBps.has_value()) j["bitrateBps"] = *v.bitrateBps;
if (v.codec.has_value()) j["codec"] = *v.codec;
if (v.container.has_value()) j["container"] = *v.container;
if (v.frameRate.has_value()) j["frameRate"] = *v.frameRate;
if (v.language.has_value()) j["language"] = *v.language;
if (v.sizeEstimate.has_value()) j["sizeEstimate"] = *v.sizeEstimate;
j["drm"] = v.drm;
}
template <> Result<MediaVariant> parse<MediaVariant>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
MediaVariant out;
{
const std::string fp = join(path, "variantId");
const auto it = j.find("variantId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.variantId = std::move(val);
}
{
const std::string fp = join(path, "kind");
const auto it = j.find("kind");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<MediaVariantKind>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.kind = std::move(val);
}
{
const std::string fp = join(path, "resolution");
const auto it = j.find("resolution");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
{
static const std::regex re("^[0-9]{2,5}x[0-9]{2,5}$", std::regex::ECMAScript);
if (!std::regex_match(val, re)) return std::unexpected(ParseError{std::string(fp), "value does not match the required pattern"});
}
out.resolution = std::move(val);
}
}
{
const std::string fp = join(path, "bitrateBps");
const auto it = j.find("bitrateBps");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.bitrateBps = std::move(val);
}
}
{
const std::string fp = join(path, "codec");
const auto it = j.find("codec");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.codec = std::move(val);
}
}
{
const std::string fp = join(path, "container");
const auto it = j.find("container");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<MediaVariantContainer>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.container = std::move(val);
}
}
{
const std::string fp = join(path, "frameRate");
const auto it = j.find("frameRate");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number()) return std::unexpected(ParseError{std::string(fp), "expected a number"});
auto val = (*it).get<double>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.frameRate = std::move(val);
}
}
{
const std::string fp = join(path, "language");
const auto it = j.find("language");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.language = std::move(val);
}
}
{
const std::string fp = join(path, "sizeEstimate");
const auto it = j.find("sizeEstimate");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.sizeEstimate = std::move(val);
}
}
{
const std::string fp = join(path, "drm");
const auto it = j.find("drm");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.drm = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const Schedule& v) {
j = nlohmann::json::object();
j["enabled"] = v.enabled;
j["mode"] = v.mode;
if (v.startTime.has_value()) j["startTime"] = *v.startTime;
if (v.stopTime.has_value()) j["stopTime"] = *v.stopTime;
if (v.daysOfWeek.has_value()) j["daysOfWeek"] = *v.daysOfWeek;
if (v.onceDate.has_value()) j["onceDate"] = *v.onceDate;
}
template <> Result<Schedule> parse<Schedule>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
Schedule out;
{
const std::string fp = join(path, "enabled");
const auto it = j.find("enabled");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.enabled = std::move(val);
}
{
const std::string fp = join(path, "mode");
const auto it = j.find("mode");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<ScheduleMode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.mode = std::move(val);
}
{
const std::string fp = join(path, "startTime");
const auto it = j.find("startTime");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
{
static const std::regex re("^([01][0-9]|2[0-3]):[0-5][0-9]$", std::regex::ECMAScript);
if (!std::regex_match(val, re)) return std::unexpected(ParseError{std::string(fp), "value does not match the required pattern"});
}
out.startTime = std::move(val);
}
}
{
const std::string fp = join(path, "stopTime");
const auto it = j.find("stopTime");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
{
static const std::regex re("^([01][0-9]|2[0-3]):[0-5][0-9]$", std::regex::ECMAScript);
if (!std::regex_match(val, re)) return std::unexpected(ParseError{std::string(fp), "value does not match the required pattern"});
}
out.stopTime = std::move(val);
}
}
{
const std::string fp = join(path, "daysOfWeek");
const auto it = j.find("daysOfWeek");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::int64_t> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_number_integer()) return std::unexpected(ParseError{std::string(ip), "expected an integer"});
auto val_e = (*it)[idx].get<std::int64_t>();
if (val_e < 0) return std::unexpected(ParseError{std::string(ip), "value is below the minimum of 0"});
if (val_e > 6) return std::unexpected(ParseError{std::string(ip), "value is above the maximum of 6"});
val.push_back(std::move(val_e));
}
out.daysOfWeek = std::move(val);
}
}
{
const std::string fp = join(path, "onceDate");
const auto it = j.find("onceDate");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.onceDate = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const Queue& v) {
j = nlohmann::json::object();
j["queueId"] = v.queueId;
j["name"] = v.name;
j["state"] = v.state;
j["maxConcurrent"] = v.maxConcurrent;
if (v.taskIds.has_value()) j["taskIds"] = *v.taskIds;
if (v.schedule.has_value()) j["schedule"] = *v.schedule;
if (v.onComplete.has_value()) j["onComplete"] = *v.onComplete;
}
template <> Result<Queue> parse<Queue>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
Queue out;
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
{
const std::string fp = join(path, "name");
const auto it = j.find("name");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 64u) return std::unexpected(ParseError{std::string(fp), "value is longer than 64 characters"});
out.name = std::move(val);
}
{
const std::string fp = join(path, "state");
const auto it = j.find("state");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<QueueState>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.state = std::move(val);
}
{
const std::string fp = join(path, "maxConcurrent");
const auto it = j.find("maxConcurrent");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 32) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 32"});
out.maxConcurrent = std::move(val);
}
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.taskIds = std::move(val);
}
}
{
const std::string fp = join(path, "schedule");
const auto it = j.find("schedule");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Schedule>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.schedule = std::move(val);
}
}
{
const std::string fp = join(path, "onComplete");
const auto it = j.find("onComplete");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<QueueOnComplete>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.onComplete = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const RuleAction& v) {
j = nlohmann::json::object();
if (v.categoryId.has_value()) j["categoryId"] = *v.categoryId;
if (v.saveDir.has_value()) j["saveDir"] = *v.saveDir;
if (v.queueId.has_value()) j["queueId"] = *v.queueId;
if (v.segments.has_value()) j["segments"] = *v.segments;
if (v.startMode.has_value()) j["startMode"] = *v.startMode;
if (v.capture.has_value()) j["capture"] = *v.capture;
}
template <> Result<RuleAction> parse<RuleAction>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
RuleAction out;
{
const std::string fp = join(path, "categoryId");
const auto it = j.find("categoryId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.categoryId = std::move(val);
}
}
{
const std::string fp = join(path, "saveDir");
const auto it = j.find("saveDir");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.saveDir = std::move(val);
}
}
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
}
{
const std::string fp = join(path, "segments");
const auto it = j.find("segments");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 32) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 32"});
out.segments = std::move(val);
}
}
{
const std::string fp = join(path, "startMode");
const auto it = j.find("startMode");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<StartMode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.startMode = std::move(val);
}
}
{
const std::string fp = join(path, "capture");
const auto it = j.find("capture");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<RuleActionCapture>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.capture = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const RuleMatch& v) {
j = nlohmann::json::object();
if (v.extensions.has_value()) j["extensions"] = *v.extensions;
if (v.mimeTypes.has_value()) j["mimeTypes"] = *v.mimeTypes;
if (v.hostPattern.has_value()) j["hostPattern"] = *v.hostPattern;
if (v.urlPattern.has_value()) j["urlPattern"] = *v.urlPattern;
if (v.minSizeBytes.has_value()) j["minSizeBytes"] = *v.minSizeBytes;
if (v.maxSizeBytes.has_value()) j["maxSizeBytes"] = *v.maxSizeBytes;
}
template <> Result<RuleMatch> parse<RuleMatch>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
RuleMatch out;
{
const std::string fp = join(path, "extensions");
const auto it = j.find("extensions");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.extensions = std::move(val);
}
}
{
const std::string fp = join(path, "mimeTypes");
const auto it = j.find("mimeTypes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.mimeTypes = std::move(val);
}
}
{
const std::string fp = join(path, "hostPattern");
const auto it = j.find("hostPattern");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.hostPattern = std::move(val);
}
}
{
const std::string fp = join(path, "urlPattern");
const auto it = j.find("urlPattern");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.urlPattern = std::move(val);
}
}
{
const std::string fp = join(path, "minSizeBytes");
const auto it = j.find("minSizeBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.minSizeBytes = std::move(val);
}
}
{
const std::string fp = join(path, "maxSizeBytes");
const auto it = j.find("maxSizeBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.maxSizeBytes = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const Rule& v) {
j = nlohmann::json::object();
j["ruleId"] = v.ruleId;
if (v.name.has_value()) j["name"] = *v.name;
j["enabled"] = v.enabled;
j["priority"] = v.priority;
j["match"] = v.match;
j["action"] = v.action;
}
template <> Result<Rule> parse<Rule>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
Rule out;
{
const std::string fp = join(path, "ruleId");
const auto it = j.find("ruleId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.ruleId = std::move(val);
}
{
const std::string fp = join(path, "name");
const auto it = j.find("name");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 64u) return std::unexpected(ParseError{std::string(fp), "value is longer than 64 characters"});
out.name = std::move(val);
}
}
{
const std::string fp = join(path, "enabled");
const auto it = j.find("enabled");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.enabled = std::move(val);
}
{
const std::string fp = join(path, "priority");
const auto it = j.find("priority");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.priority = std::move(val);
}
{
const std::string fp = join(path, "match");
const auto it = j.find("match");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<RuleMatch>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.match = std::move(val);
}
{
const std::string fp = join(path, "action");
const auto it = j.find("action");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<RuleAction>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.action = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const Segment& v) {
j = nlohmann::json::object();
j["index"] = v.index;
j["startByte"] = v.startByte;
j["endByte"] = v.endByte;
j["downloadedBytes"] = v.downloadedBytes;
if (v.speedBps.has_value()) j["speedBps"] = *v.speedBps;
j["state"] = v.state;
if (v.httpStatus.has_value()) j["httpStatus"] = *v.httpStatus;
}
template <> Result<Segment> parse<Segment>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
Segment out;
{
const std::string fp = join(path, "index");
const auto it = j.find("index");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
if (val > 31) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 31"});
out.index = std::move(val);
}
{
const std::string fp = join(path, "startByte");
const auto it = j.find("startByte");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.startByte = std::move(val);
}
{
const std::string fp = join(path, "endByte");
const auto it = j.find("endByte");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.endByte = std::move(val);
}
{
const std::string fp = join(path, "downloadedBytes");
const auto it = j.find("downloadedBytes");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.downloadedBytes = std::move(val);
}
{
const std::string fp = join(path, "speedBps");
const auto it = j.find("speedBps");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.speedBps = std::move(val);
}
}
{
const std::string fp = join(path, "state");
const auto it = j.find("state");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<SegmentState>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.state = std::move(val);
}
{
const std::string fp = join(path, "httpStatus");
const auto it = j.find("httpStatus");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 100) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 100"});
if (val > 599) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 599"});
out.httpStatus = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const Settings& v) {
j = nlohmann::json::object();
if (v.general_launchOnLogin.has_value()) j["general.launchOnLogin"] = *v.general_launchOnLogin;
if (v.general_minimizeToTray.has_value()) j["general.minimizeToTray"] = *v.general_minimizeToTray;
if (v.general_showDropTarget.has_value()) j["general.showDropTarget"] = *v.general_showDropTarget;
if (v.general_confirmOnExit.has_value()) j["general.confirmOnExit"] = *v.general_confirmOnExit;
if (v.general_language.has_value()) j["general.language"] = *v.general_language;
if (v.general_checkForUpdates.has_value()) j["general.checkForUpdates"] = *v.general_checkForUpdates;
if (v.capture_enabled.has_value()) j["capture.enabled"] = *v.capture_enabled;
if (v.capture_monitoredExtensions.has_value()) j["capture.monitoredExtensions"] = *v.capture_monitoredExtensions;
if (v.capture_monitoredMimeTypes.has_value()) j["capture.monitoredMimeTypes"] = *v.capture_monitoredMimeTypes;
if (v.capture_minSizeBytes.has_value()) j["capture.minSizeBytes"] = *v.capture_minSizeBytes;
if (v.capture_excludedHosts.has_value()) j["capture.excludedHosts"] = *v.capture_excludedHosts;
if (v.capture_bypassModifier.has_value()) j["capture.bypassModifier"] = *v.capture_bypassModifier;
if (v.capture_autoStartTypes.has_value()) j["capture.autoStartTypes"] = *v.capture_autoStartTypes;
if (v.saveTo_defaultDir.has_value()) j["saveTo.defaultDir"] = *v.saveTo_defaultDir;
if (v.saveTo_tempDir.has_value()) j["saveTo.tempDir"] = *v.saveTo_tempDir;
if (v.saveTo_allowedRoots.has_value()) j["saveTo.allowedRoots"] = *v.saveTo_allowedRoots;
if (v.saveTo_fileExistsPolicy.has_value()) j["saveTo.fileExistsPolicy"] = *v.saveTo_fileExistsPolicy;
if (v.saveTo_createSubfolderPerSite.has_value()) j["saveTo.createSubfolderPerSite"] = *v.saveTo_createSubfolderPerSite;
if (v.connection_preset.has_value()) j["connection.preset"] = *v.connection_preset;
if (v.connection_maxSegmentsPerDownload.has_value()) j["connection.maxSegmentsPerDownload"] = *v.connection_maxSegmentsPerDownload;
if (v.connection_bufferBytes.has_value()) j["connection.bufferBytes"] = *v.connection_bufferBytes;
if (v.connection_maxConcurrentDownloads.has_value()) j["connection.maxConcurrentDownloads"] = *v.connection_maxConcurrentDownloads;
if (v.connection_timeoutSec.has_value()) j["connection.timeoutSec"] = *v.connection_timeoutSec;
if (v.connection_maxRetries.has_value()) j["connection.maxRetries"] = *v.connection_maxRetries;
if (v.connection_retryBackoffSec.has_value()) j["connection.retryBackoffSec"] = *v.connection_retryBackoffSec;
if (v.downloads_speedLimitBps.has_value()) j["downloads.speedLimitBps"] = *v.downloads_speedLimitBps;
if (v.downloads_speedLimitEnabled.has_value()) j["downloads.speedLimitEnabled"] = *v.downloads_speedLimitEnabled;
if (v.downloads_virusScanCommand.has_value()) j["downloads.virusScanCommand"] = *v.downloads_virusScanCommand;
if (v.downloads_postDownloadCommand.has_value()) j["downloads.postDownloadCommand"] = *v.downloads_postDownloadCommand;
if (v.downloads_duplicatePolicy.has_value()) j["downloads.duplicatePolicy"] = *v.downloads_duplicatePolicy;
if (v.downloads_verifyChecksums.has_value()) j["downloads.verifyChecksums"] = *v.downloads_verifyChecksums;
if (v.proxy_mode.has_value()) j["proxy.mode"] = *v.proxy_mode;
if (v.proxy_host.has_value()) j["proxy.host"] = *v.proxy_host;
if (v.proxy_port.has_value()) j["proxy.port"] = *v.proxy_port;
if (v.proxy_username.has_value()) j["proxy.username"] = *v.proxy_username;
if (v.proxy_bypassHosts.has_value()) j["proxy.bypassHosts"] = *v.proxy_bypassHosts;
if (v.proxy_pacUrl.has_value()) j["proxy.pacUrl"] = *v.proxy_pacUrl;
if (v.sounds_enabled.has_value()) j["sounds.enabled"] = *v.sounds_enabled;
if (v.sounds_onComplete.has_value()) j["sounds.onComplete"] = *v.sounds_onComplete;
if (v.sounds_onQueueComplete.has_value()) j["sounds.onQueueComplete"] = *v.sounds_onQueueComplete;
if (v.sounds_onError.has_value()) j["sounds.onError"] = *v.sounds_onError;
}
template <> Result<Settings> parse<Settings>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
Settings out;
{
const std::string fp = join(path, "general.launchOnLogin");
const auto it = j.find("general.launchOnLogin");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.general_launchOnLogin = std::move(val);
}
}
{
const std::string fp = join(path, "general.minimizeToTray");
const auto it = j.find("general.minimizeToTray");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.general_minimizeToTray = std::move(val);
}
}
{
const std::string fp = join(path, "general.showDropTarget");
const auto it = j.find("general.showDropTarget");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.general_showDropTarget = std::move(val);
}
}
{
const std::string fp = join(path, "general.confirmOnExit");
const auto it = j.find("general.confirmOnExit");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.general_confirmOnExit = std::move(val);
}
}
{
const std::string fp = join(path, "general.language");
const auto it = j.find("general.language");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.general_language = std::move(val);
}
}
{
const std::string fp = join(path, "general.checkForUpdates");
const auto it = j.find("general.checkForUpdates");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.general_checkForUpdates = std::move(val);
}
}
{
const std::string fp = join(path, "capture.enabled");
const auto it = j.find("capture.enabled");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.capture_enabled = std::move(val);
}
}
{
const std::string fp = join(path, "capture.monitoredExtensions");
const auto it = j.find("capture.monitoredExtensions");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.capture_monitoredExtensions = std::move(val);
}
}
{
const std::string fp = join(path, "capture.monitoredMimeTypes");
const auto it = j.find("capture.monitoredMimeTypes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.capture_monitoredMimeTypes = std::move(val);
}
}
{
const std::string fp = join(path, "capture.minSizeBytes");
const auto it = j.find("capture.minSizeBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.capture_minSizeBytes = std::move(val);
}
}
{
const std::string fp = join(path, "capture.excludedHosts");
const auto it = j.find("capture.excludedHosts");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.capture_excludedHosts = std::move(val);
}
}
{
const std::string fp = join(path, "capture.bypassModifier");
const auto it = j.find("capture.bypassModifier");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<BypassModifier>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.capture_bypassModifier = std::move(val);
}
}
{
const std::string fp = join(path, "capture.autoStartTypes");
const auto it = j.find("capture.autoStartTypes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.capture_autoStartTypes = std::move(val);
}
}
{
const std::string fp = join(path, "saveTo.defaultDir");
const auto it = j.find("saveTo.defaultDir");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.saveTo_defaultDir = std::move(val);
}
}
{
const std::string fp = join(path, "saveTo.tempDir");
const auto it = j.find("saveTo.tempDir");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.saveTo_tempDir = std::move(val);
}
}
{
const std::string fp = join(path, "saveTo.allowedRoots");
const auto it = j.find("saveTo.allowedRoots");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.saveTo_allowedRoots = std::move(val);
}
}
{
const std::string fp = join(path, "saveTo.fileExistsPolicy");
const auto it = j.find("saveTo.fileExistsPolicy");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<SettingsSaveToFileExistsPolicy>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.saveTo_fileExistsPolicy = std::move(val);
}
}
{
const std::string fp = join(path, "saveTo.createSubfolderPerSite");
const auto it = j.find("saveTo.createSubfolderPerSite");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.saveTo_createSubfolderPerSite = std::move(val);
}
}
{
const std::string fp = join(path, "connection.preset");
const auto it = j.find("connection.preset");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<SettingsConnectionPreset>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.connection_preset = std::move(val);
}
}
{
const std::string fp = join(path, "connection.maxSegmentsPerDownload");
const auto it = j.find("connection.maxSegmentsPerDownload");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 32) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 32"});
out.connection_maxSegmentsPerDownload = std::move(val);
}
}
{
const std::string fp = join(path, "connection.bufferBytes");
const auto it = j.find("connection.bufferBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 4096) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 4096"});
if (val > 8388608) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 8388608"});
out.connection_bufferBytes = std::move(val);
}
}
{
const std::string fp = join(path, "connection.maxConcurrentDownloads");
const auto it = j.find("connection.maxConcurrentDownloads");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 64) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 64"});
out.connection_maxConcurrentDownloads = std::move(val);
}
}
{
const std::string fp = join(path, "connection.timeoutSec");
const auto it = j.find("connection.timeoutSec");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 3600) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 3600"});
out.connection_timeoutSec = std::move(val);
}
}
{
const std::string fp = join(path, "connection.maxRetries");
const auto it = j.find("connection.maxRetries");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
if (val > 100) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 100"});
out.connection_maxRetries = std::move(val);
}
}
{
const std::string fp = join(path, "connection.retryBackoffSec");
const auto it = j.find("connection.retryBackoffSec");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
if (val > 3600) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 3600"});
out.connection_retryBackoffSec = std::move(val);
}
}
{
const std::string fp = join(path, "downloads.speedLimitBps");
const auto it = j.find("downloads.speedLimitBps");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.downloads_speedLimitBps = std::move(val);
}
}
{
const std::string fp = join(path, "downloads.speedLimitEnabled");
const auto it = j.find("downloads.speedLimitEnabled");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.downloads_speedLimitEnabled = std::move(val);
}
}
{
const std::string fp = join(path, "downloads.virusScanCommand");
const auto it = j.find("downloads.virusScanCommand");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.downloads_virusScanCommand = std::move(val);
}
}
{
const std::string fp = join(path, "downloads.postDownloadCommand");
const auto it = j.find("downloads.postDownloadCommand");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.downloads_postDownloadCommand = std::move(val);
}
}
{
const std::string fp = join(path, "downloads.duplicatePolicy");
const auto it = j.find("downloads.duplicatePolicy");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<SettingsDownloadsDuplicatePolicy>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.downloads_duplicatePolicy = std::move(val);
}
}
{
const std::string fp = join(path, "downloads.verifyChecksums");
const auto it = j.find("downloads.verifyChecksums");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.downloads_verifyChecksums = std::move(val);
}
}
{
const std::string fp = join(path, "proxy.mode");
const auto it = j.find("proxy.mode");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<SettingsProxyMode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.proxy_mode = std::move(val);
}
}
{
const std::string fp = join(path, "proxy.host");
const auto it = j.find("proxy.host");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.proxy_host = std::move(val);
}
}
{
const std::string fp = join(path, "proxy.port");
const auto it = j.find("proxy.port");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 65535) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 65535"});
out.proxy_port = std::move(val);
}
}
{
const std::string fp = join(path, "proxy.username");
const auto it = j.find("proxy.username");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.proxy_username = std::move(val);
}
}
{
const std::string fp = join(path, "proxy.bypassHosts");
const auto it = j.find("proxy.bypassHosts");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.proxy_bypassHosts = std::move(val);
}
}
{
const std::string fp = join(path, "proxy.pacUrl");
const auto it = j.find("proxy.pacUrl");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.proxy_pacUrl = std::move(val);
}
}
{
const std::string fp = join(path, "sounds.enabled");
const auto it = j.find("sounds.enabled");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.sounds_enabled = std::move(val);
}
}
{
const std::string fp = join(path, "sounds.onComplete");
const auto it = j.find("sounds.onComplete");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.sounds_onComplete = std::move(val);
}
}
{
const std::string fp = join(path, "sounds.onQueueComplete");
const auto it = j.find("sounds.onQueueComplete");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.sounds_onQueueComplete = std::move(val);
}
}
{
const std::string fp = join(path, "sounds.onError");
const auto it = j.find("sounds.onError");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.sounds_onError = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const TaskError& v) {
j = nlohmann::json::object();
j["code"] = v.code;
j["message"] = v.message;
if (v.httpStatus.has_value()) j["httpStatus"] = *v.httpStatus;
j["retryable"] = v.retryable;
if (v.cause.has_value()) j["cause"] = *v.cause;
if (v.attempt.has_value()) j["attempt"] = *v.attempt;
if (v.nextRetryAt.has_value()) j["nextRetryAt"] = *v.nextRetryAt;
}
template <> Result<TaskError> parse<TaskError>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskError out;
{
const std::string fp = join(path, "code");
const auto it = j.find("code");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskErrorCode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.code = std::move(val);
}
{
const std::string fp = join(path, "message");
const auto it = j.find("message");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.message = std::move(val);
}
{
const std::string fp = join(path, "httpStatus");
const auto it = j.find("httpStatus");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 100) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 100"});
if (val > 599) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 599"});
out.httpStatus = std::move(val);
}
}
{
const std::string fp = join(path, "retryable");
const auto it = j.find("retryable");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.retryable = std::move(val);
}
{
const std::string fp = join(path, "cause");
const auto it = j.find("cause");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<TaskErrorCode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.cause = std::move(val);
}
}
{
const std::string fp = join(path, "attempt");
const auto it = j.find("attempt");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.attempt = std::move(val);
}
}
{
const std::string fp = join(path, "nextRetryAt");
const auto it = j.find("nextRetryAt");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.nextRetryAt = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const TaskSummary& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["filename"] = v.filename;
j["saveDir"] = v.saveDir;
j["url"] = v.url;
if (v.effectiveUrl.has_value()) j["effectiveUrl"] = *v.effectiveUrl;
if (v.sizeBytes.has_value()) j["sizeBytes"] = *v.sizeBytes;
j["downloadedBytes"] = v.downloadedBytes;
j["state"] = v.state;
j["speedBps"] = v.speedBps;
if (v.etaSeconds.has_value()) j["etaSeconds"] = *v.etaSeconds;
j["resumable"] = v.resumable;
j["segments"] = v.segments;
if (v.categoryId.has_value()) j["categoryId"] = *v.categoryId;
if (v.queueId.has_value()) j["queueId"] = *v.queueId;
if (v.queuePosition.has_value()) j["queuePosition"] = *v.queuePosition;
if (v.description.has_value()) j["description"] = *v.description;
j["createdAt"] = v.createdAt;
if (v.lastTryAt.has_value()) j["lastTryAt"] = *v.lastTryAt;
if (v.completedAt.has_value()) j["completedAt"] = *v.completedAt;
if (v.error.has_value()) j["error"] = *v.error;
}
template <> Result<TaskSummary> parse<TaskSummary>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskSummary out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "filename");
const auto it = j.find("filename");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 255u) return std::unexpected(ParseError{std::string(fp), "value is longer than 255 characters"});
out.filename = std::move(val);
}
{
const std::string fp = join(path, "saveDir");
const auto it = j.find("saveDir");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.saveDir = std::move(val);
}
{
const std::string fp = join(path, "url");
const auto it = j.find("url");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.url = std::move(val);
}
{
const std::string fp = join(path, "effectiveUrl");
const auto it = j.find("effectiveUrl");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.effectiveUrl = std::move(val);
}
}
{
const std::string fp = join(path, "sizeBytes");
const auto it = j.find("sizeBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.sizeBytes = std::move(val);
}
}
{
const std::string fp = join(path, "downloadedBytes");
const auto it = j.find("downloadedBytes");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.downloadedBytes = std::move(val);
}
{
const std::string fp = join(path, "state");
const auto it = j.find("state");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskState>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.state = std::move(val);
}
{
const std::string fp = join(path, "speedBps");
const auto it = j.find("speedBps");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.speedBps = std::move(val);
}
{
const std::string fp = join(path, "etaSeconds");
const auto it = j.find("etaSeconds");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.etaSeconds = std::move(val);
}
}
{
const std::string fp = join(path, "resumable");
const auto it = j.find("resumable");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.resumable = std::move(val);
}
{
const std::string fp = join(path, "segments");
const auto it = j.find("segments");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 32) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 32"});
out.segments = std::move(val);
}
{
const std::string fp = join(path, "categoryId");
const auto it = j.find("categoryId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.categoryId = std::move(val);
}
}
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
}
{
const std::string fp = join(path, "queuePosition");
const auto it = j.find("queuePosition");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.queuePosition = std::move(val);
}
}
{
const std::string fp = join(path, "description");
const auto it = j.find("description");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 1024u) return std::unexpected(ParseError{std::string(fp), "value is longer than 1024 characters"});
out.description = std::move(val);
}
}
{
const std::string fp = join(path, "createdAt");
const auto it = j.find("createdAt");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.createdAt = std::move(val);
}
{
const std::string fp = join(path, "lastTryAt");
const auto it = j.find("lastTryAt");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.lastTryAt = std::move(val);
}
}
{
const std::string fp = join(path, "completedAt");
const auto it = j.find("completedAt");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.completedAt = std::move(val);
}
}
{
const std::string fp = join(path, "error");
const auto it = j.find("error");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<TaskError>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.error = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const TaskDetail& v) {
j = nlohmann::json::object();
j["summary"] = v.summary;
j["segmentDetail"] = v.segmentDetail;
if (v.headers.has_value()) j["headers"] = *v.headers;
if (v.referrer.has_value()) j["referrer"] = *v.referrer;
if (v.userAgent.has_value()) j["userAgent"] = *v.userAgent;
if (v.mime.has_value()) j["mime"] = *v.mime;
if (v.bufferBytes.has_value()) j["bufferBytes"] = *v.bufferBytes;
if (v.partPath.has_value()) j["partPath"] = *v.partPath;
if (v.checksum.has_value()) j["checksum"] = *v.checksum;
if (v.checksumVerified.has_value()) j["checksumVerified"] = *v.checksumVerified;
if (v.averageSpeedBps.has_value()) j["averageSpeedBps"] = *v.averageSpeedBps;
if (v.retryCount.has_value()) j["retryCount"] = *v.retryCount;
}
template <> Result<TaskDetail> parse<TaskDetail>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskDetail out;
{
const std::string fp = join(path, "summary");
const auto it = j.find("summary");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskSummary>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.summary = std::move(val);
}
{
const std::string fp = join(path, "segmentDetail");
const auto it = j.find("segmentDetail");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Segment> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Segment>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
if (val.size() > 32u) return std::unexpected(ParseError{std::string(fp), "more than 32 items"});
out.segmentDetail = std::move(val);
}
{
const std::string fp = join(path, "headers");
const auto it = j.find("headers");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Headers>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.headers = std::move(val);
}
}
{
const std::string fp = join(path, "referrer");
const auto it = j.find("referrer");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.referrer = std::move(val);
}
}
{
const std::string fp = join(path, "userAgent");
const auto it = j.find("userAgent");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.userAgent = std::move(val);
}
}
{
const std::string fp = join(path, "mime");
const auto it = j.find("mime");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.mime = std::move(val);
}
}
{
const std::string fp = join(path, "bufferBytes");
const auto it = j.find("bufferBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 4096) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 4096"});
if (val > 8388608) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 8388608"});
out.bufferBytes = std::move(val);
}
}
{
const std::string fp = join(path, "partPath");
const auto it = j.find("partPath");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.partPath = std::move(val);
}
}
{
const std::string fp = join(path, "checksum");
const auto it = j.find("checksum");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Checksum>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.checksum = std::move(val);
}
}
{
const std::string fp = join(path, "checksumVerified");
const auto it = j.find("checksumVerified");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.checksumVerified = std::move(val);
}
}
{
const std::string fp = join(path, "averageSpeedBps");
const auto it = j.find("averageSpeedBps");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.averageSpeedBps = std::move(val);
}
}
{
const std::string fp = join(path, "retryCount");
const auto it = j.find("retryCount");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.retryCount = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const TaskFilter& v) {
j = nlohmann::json::object();
if (v.states.has_value()) j["states"] = *v.states;
if (v.categoryId.has_value()) j["categoryId"] = *v.categoryId;
if (v.queueId.has_value()) j["queueId"] = *v.queueId;
if (v.query.has_value()) j["query"] = *v.query;
if (v.addedAfter.has_value()) j["addedAfter"] = *v.addedAfter;
if (v.addedBefore.has_value()) j["addedBefore"] = *v.addedBefore;
}
template <> Result<TaskFilter> parse<TaskFilter>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskFilter out;
{
const std::string fp = join(path, "states");
const auto it = j.find("states");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<TaskState> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<TaskState>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.states = std::move(val);
}
}
{
const std::string fp = join(path, "categoryId");
const auto it = j.find("categoryId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.categoryId = std::move(val);
}
}
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
}
{
const std::string fp = join(path, "query");
const auto it = j.find("query");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 256u) return std::unexpected(ParseError{std::string(fp), "value is longer than 256 characters"});
out.query = std::move(val);
}
}
{
const std::string fp = join(path, "addedAfter");
const auto it = j.find("addedAfter");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.addedAfter = std::move(val);
}
}
{
const std::string fp = join(path, "addedBefore");
const auto it = j.find("addedBefore");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.addedBefore = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const TaskSort& v) {
j = nlohmann::json::object();
j["field"] = v.field;
j["direction"] = v.direction;
}
template <> Result<TaskSort> parse<TaskSort>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskSort out;
{
const std::string fp = join(path, "field");
const auto it = j.find("field");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskSortField>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.field = std::move(val);
}
{
const std::string fp = join(path, "direction");
const auto it = j.find("direction");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskSortDirection>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.direction = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const CaptureGetRulesParams& /*v*/) {
j = nlohmann::json::object();
}
template <> Result<CaptureGetRulesParams> parse<CaptureGetRulesParams>(const nlohmann::json& j, std::string_view /*path*/) {
if (!j.is_object()) return std::unexpected(ParseError{"", "expected an object"});
CaptureGetRulesParams out;
return out;
}
void to_json(nlohmann::json& j, const CaptureOfferParams& v) {
j = nlohmann::json::object();
j["url"] = v.url;
j["method"] = v.method;
j["tabUrl"] = v.tabUrl;
if (v.headers.has_value()) j["headers"] = *v.headers;
if (v.cookies.has_value()) j["cookies"] = *v.cookies;
if (v.contentType.has_value()) j["contentType"] = *v.contentType;
if (v.contentLength.has_value()) j["contentLength"] = *v.contentLength;
if (v.contentDisposition.has_value()) j["contentDisposition"] = *v.contentDisposition;
if (v.filename.has_value()) j["filename"] = *v.filename;
if (v.userAgent.has_value()) j["userAgent"] = *v.userAgent;
if (v.referrer.has_value()) j["referrer"] = *v.referrer;
if (v.origin.has_value()) j["origin"] = *v.origin;
if (v.requestId.has_value()) j["requestId"] = *v.requestId;
}
template <> Result<CaptureOfferParams> parse<CaptureOfferParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
CaptureOfferParams out;
{
const std::string fp = join(path, "url");
const auto it = j.find("url");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.url = std::move(val);
}
{
const std::string fp = join(path, "method");
const auto it = j.find("method");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<CaptureOfferParamsMethod>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.method = std::move(val);
}
{
const std::string fp = join(path, "tabUrl");
const auto it = j.find("tabUrl");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.tabUrl = std::move(val);
}
{
const std::string fp = join(path, "headers");
const auto it = j.find("headers");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Headers>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.headers = std::move(val);
}
}
{
const std::string fp = join(path, "cookies");
const auto it = j.find("cookies");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Cookie> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Cookie>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.cookies = std::move(val);
}
}
{
const std::string fp = join(path, "contentType");
const auto it = j.find("contentType");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.contentType = std::move(val);
}
}
{
const std::string fp = join(path, "contentLength");
const auto it = j.find("contentLength");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.contentLength = std::move(val);
}
}
{
const std::string fp = join(path, "contentDisposition");
const auto it = j.find("contentDisposition");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.contentDisposition = std::move(val);
}
}
{
const std::string fp = join(path, "filename");
const auto it = j.find("filename");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.filename = std::move(val);
}
}
{
const std::string fp = join(path, "userAgent");
const auto it = j.find("userAgent");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.userAgent = std::move(val);
}
}
{
const std::string fp = join(path, "referrer");
const auto it = j.find("referrer");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.referrer = std::move(val);
}
}
{
const std::string fp = join(path, "origin");
const auto it = j.find("origin");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.origin = std::move(val);
}
}
{
const std::string fp = join(path, "requestId");
const auto it = j.find("requestId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.requestId = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const CaptureOfferResult& v) {
j = nlohmann::json::object();
j["action"] = v.action;
if (v.taskId.has_value()) j["taskId"] = *v.taskId;
if (v.reason.has_value()) j["reason"] = *v.reason;
}
template <> Result<CaptureOfferResult> parse<CaptureOfferResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
CaptureOfferResult out;
{
const std::string fp = join(path, "action");
const auto it = j.find("action");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<CaptureOfferResultAction>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.action = std::move(val);
}
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
}
{
const std::string fp = join(path, "reason");
const auto it = j.find("reason");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<CaptureOfferResultReason>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.reason = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const CategoryListParams& /*v*/) {
j = nlohmann::json::object();
}
template <> Result<CategoryListParams> parse<CategoryListParams>(const nlohmann::json& j, std::string_view /*path*/) {
if (!j.is_object()) return std::unexpected(ParseError{"", "expected an object"});
CategoryListParams out;
return out;
}
void to_json(nlohmann::json& j, const CategoryListResult& v) {
j = nlohmann::json::object();
j["items"] = v.items;
}
template <> Result<CategoryListResult> parse<CategoryListResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
CategoryListResult out;
{
const std::string fp = join(path, "items");
const auto it = j.find("items");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Category> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Category>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.items = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const CategoryRemoveParams& v) {
j = nlohmann::json::object();
j["categoryId"] = v.categoryId;
if (v.reassignTo.has_value()) j["reassignTo"] = *v.reassignTo;
}
template <> Result<CategoryRemoveParams> parse<CategoryRemoveParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
CategoryRemoveParams out;
{
const std::string fp = join(path, "categoryId");
const auto it = j.find("categoryId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.categoryId = std::move(val);
}
{
const std::string fp = join(path, "reassignTo");
const auto it = j.find("reassignTo");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.reassignTo = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const CategoryRemoveResult& v) {
j = nlohmann::json::object();
j["removed"] = v.removed;
j["reassignedTaskIds"] = v.reassignedTaskIds;
}
template <> Result<CategoryRemoveResult> parse<CategoryRemoveResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
CategoryRemoveResult out;
{
const std::string fp = join(path, "removed");
const auto it = j.find("removed");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.removed = std::move(val);
}
{
const std::string fp = join(path, "reassignedTaskIds");
const auto it = j.find("reassignedTaskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.reassignedTaskIds = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const CategoryUpsertParams& v) {
j = nlohmann::json::object();
j["category"] = v.category;
}
template <> Result<CategoryUpsertParams> parse<CategoryUpsertParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
CategoryUpsertParams out;
{
const std::string fp = join(path, "category");
const auto it = j.find("category");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Category>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.category = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const CategoryUpsertResult& v) {
j = nlohmann::json::object();
j["category"] = v.category;
}
template <> Result<CategoryUpsertResult> parse<CategoryUpsertResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
CategoryUpsertResult out;
{
const std::string fp = join(path, "category");
const auto it = j.find("category");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Category>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.category = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadAddResult& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["state"] = v.state;
if (v.duplicate.has_value()) j["duplicate"] = *v.duplicate;
}
template <> Result<DownloadAddResult> parse<DownloadAddResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadAddResult out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "state");
const auto it = j.find("state");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskState>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.state = std::move(val);
}
{
const std::string fp = join(path, "duplicate");
const auto it = j.find("duplicate");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.duplicate = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const DownloadAddBatchParams& v) {
j = nlohmann::json::object();
j["items"] = v.items;
if (v.defaults.has_value()) j["defaults"] = *v.defaults;
}
template <> Result<DownloadAddBatchParams> parse<DownloadAddBatchParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadAddBatchParams out;
{
const std::string fp = join(path, "items");
const auto it = j.find("items");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<DownloadSpec> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<DownloadSpec>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
if (val.size() < 1u) return std::unexpected(ParseError{std::string(fp), "fewer than 1 items"});
if (val.size() > 5000u) return std::unexpected(ParseError{std::string(fp), "more than 5000 items"});
out.items = std::move(val);
}
{
const std::string fp = join(path, "defaults");
const auto it = j.find("defaults");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<DownloadSpec>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.defaults = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const DownloadAddBatchResultFailedItem& v) {
j = nlohmann::json::object();
j["index"] = v.index;
j["code"] = v.code;
j["message"] = v.message;
}
template <> Result<DownloadAddBatchResultFailedItem> parse<DownloadAddBatchResultFailedItem>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadAddBatchResultFailedItem out;
{
const std::string fp = join(path, "index");
const auto it = j.find("index");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.index = std::move(val);
}
{
const std::string fp = join(path, "code");
const auto it = j.find("code");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<ErrorCode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.code = std::move(val);
}
{
const std::string fp = join(path, "message");
const auto it = j.find("message");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.message = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadAddBatchResult& v) {
j = nlohmann::json::object();
j["taskIds"] = v.taskIds;
j["failed"] = v.failed;
}
template <> Result<DownloadAddBatchResult> parse<DownloadAddBatchResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadAddBatchResult out;
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.taskIds = std::move(val);
}
{
const std::string fp = join(path, "failed");
const auto it = j.find("failed");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<DownloadAddBatchResultFailedItem> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<DownloadAddBatchResultFailedItem>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.failed = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadCancelParams& v) {
j = nlohmann::json::object();
j["taskIds"] = v.taskIds;
}
template <> Result<DownloadCancelParams> parse<DownloadCancelParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadCancelParams out;
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
if (val.size() < 1u) return std::unexpected(ParseError{std::string(fp), "fewer than 1 items"});
if (val.size() > 5000u) return std::unexpected(ParseError{std::string(fp), "more than 5000 items"});
out.taskIds = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadGetParams& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
}
template <> Result<DownloadGetParams> parse<DownloadGetParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadGetParams out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadListParams& v) {
j = nlohmann::json::object();
if (v.filter.has_value()) j["filter"] = *v.filter;
if (v.sort.has_value()) j["sort"] = *v.sort;
if (v.offset.has_value()) j["offset"] = *v.offset;
if (v.limit.has_value()) j["limit"] = *v.limit;
}
template <> Result<DownloadListParams> parse<DownloadListParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadListParams out;
{
const std::string fp = join(path, "filter");
const auto it = j.find("filter");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<TaskFilter>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.filter = std::move(val);
}
}
{
const std::string fp = join(path, "sort");
const auto it = j.find("sort");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<TaskSort>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.sort = std::move(val);
}
}
{
const std::string fp = join(path, "offset");
const auto it = j.find("offset");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.offset = std::move(val);
}
}
{
const std::string fp = join(path, "limit");
const auto it = j.find("limit");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 5000) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 5000"});
out.limit = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const DownloadListResult& v) {
j = nlohmann::json::object();
j["total"] = v.total;
j["items"] = v.items;
}
template <> Result<DownloadListResult> parse<DownloadListResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadListResult out;
{
const std::string fp = join(path, "total");
const auto it = j.find("total");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.total = std::move(val);
}
{
const std::string fp = join(path, "items");
const auto it = j.find("items");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<TaskSummary> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<TaskSummary>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.items = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadPauseParams& v) {
j = nlohmann::json::object();
j["taskIds"] = v.taskIds;
}
template <> Result<DownloadPauseParams> parse<DownloadPauseParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadPauseParams out;
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
if (val.size() < 1u) return std::unexpected(ParseError{std::string(fp), "fewer than 1 items"});
if (val.size() > 5000u) return std::unexpected(ParseError{std::string(fp), "more than 5000 items"});
out.taskIds = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadProbeParams& v) {
j = nlohmann::json::object();
j["url"] = v.url;
if (v.headers.has_value()) j["headers"] = *v.headers;
if (v.cookies.has_value()) j["cookies"] = *v.cookies;
if (v.referrer.has_value()) j["referrer"] = *v.referrer;
if (v.userAgent.has_value()) j["userAgent"] = *v.userAgent;
}
template <> Result<DownloadProbeParams> parse<DownloadProbeParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadProbeParams out;
{
const std::string fp = join(path, "url");
const auto it = j.find("url");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.url = std::move(val);
}
{
const std::string fp = join(path, "headers");
const auto it = j.find("headers");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Headers>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.headers = std::move(val);
}
}
{
const std::string fp = join(path, "cookies");
const auto it = j.find("cookies");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Cookie> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Cookie>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.cookies = std::move(val);
}
}
{
const std::string fp = join(path, "referrer");
const auto it = j.find("referrer");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.referrer = std::move(val);
}
}
{
const std::string fp = join(path, "userAgent");
const auto it = j.find("userAgent");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.userAgent = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const DownloadProbeResult& v) {
j = nlohmann::json::object();
j["filename"] = v.filename;
if (v.sizeBytes.has_value()) j["sizeBytes"] = *v.sizeBytes;
j["mime"] = v.mime;
j["resumable"] = v.resumable;
j["effectiveUrl"] = v.effectiveUrl;
j["suggestedCategoryId"] = v.suggestedCategoryId;
if (v.suggestedSaveDir.has_value()) j["suggestedSaveDir"] = *v.suggestedSaveDir;
if (v.etag.has_value()) j["etag"] = *v.etag;
if (v.lastModified.has_value()) j["lastModified"] = *v.lastModified;
if (v.acceptRanges.has_value()) j["acceptRanges"] = *v.acceptRanges;
if (v.redirectChain.has_value()) j["redirectChain"] = *v.redirectChain;
if (v.requiresAuth.has_value()) j["requiresAuth"] = *v.requiresAuth;
}
template <> Result<DownloadProbeResult> parse<DownloadProbeResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadProbeResult out;
{
const std::string fp = join(path, "filename");
const auto it = j.find("filename");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.filename = std::move(val);
}
{
const std::string fp = join(path, "sizeBytes");
const auto it = j.find("sizeBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.sizeBytes = std::move(val);
}
}
{
const std::string fp = join(path, "mime");
const auto it = j.find("mime");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.mime = std::move(val);
}
{
const std::string fp = join(path, "resumable");
const auto it = j.find("resumable");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.resumable = std::move(val);
}
{
const std::string fp = join(path, "effectiveUrl");
const auto it = j.find("effectiveUrl");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.effectiveUrl = std::move(val);
}
{
const std::string fp = join(path, "suggestedCategoryId");
const auto it = j.find("suggestedCategoryId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.suggestedCategoryId = std::move(val);
}
{
const std::string fp = join(path, "suggestedSaveDir");
const auto it = j.find("suggestedSaveDir");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.suggestedSaveDir = std::move(val);
}
}
{
const std::string fp = join(path, "etag");
const auto it = j.find("etag");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.etag = std::move(val);
}
}
{
const std::string fp = join(path, "lastModified");
const auto it = j.find("lastModified");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.lastModified = std::move(val);
}
}
{
const std::string fp = join(path, "acceptRanges");
const auto it = j.find("acceptRanges");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.acceptRanges = std::move(val);
}
}
{
const std::string fp = join(path, "redirectChain");
const auto it = j.find("redirectChain");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.redirectChain = std::move(val);
}
}
{
const std::string fp = join(path, "requiresAuth");
const auto it = j.find("requiresAuth");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.requiresAuth = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const DownloadRefreshUrlParams& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["url"] = v.url;
if (v.headers.has_value()) j["headers"] = *v.headers;
if (v.cookies.has_value()) j["cookies"] = *v.cookies;
}
template <> Result<DownloadRefreshUrlParams> parse<DownloadRefreshUrlParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadRefreshUrlParams out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "url");
const auto it = j.find("url");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.url = std::move(val);
}
{
const std::string fp = join(path, "headers");
const auto it = j.find("headers");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Headers>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.headers = std::move(val);
}
}
{
const std::string fp = join(path, "cookies");
const auto it = j.find("cookies");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Cookie> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Cookie>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.cookies = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const DownloadRefreshUrlResult& v) {
j = nlohmann::json::object();
j["ok"] = v.ok;
j["resumable"] = v.resumable;
j["contentChanged"] = v.contentChanged;
if (v.sizeBytes.has_value()) j["sizeBytes"] = *v.sizeBytes;
if (v.effectiveUrl.has_value()) j["effectiveUrl"] = *v.effectiveUrl;
}
template <> Result<DownloadRefreshUrlResult> parse<DownloadRefreshUrlResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadRefreshUrlResult out;
{
const std::string fp = join(path, "ok");
const auto it = j.find("ok");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.ok = std::move(val);
}
{
const std::string fp = join(path, "resumable");
const auto it = j.find("resumable");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.resumable = std::move(val);
}
{
const std::string fp = join(path, "contentChanged");
const auto it = j.find("contentChanged");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.contentChanged = std::move(val);
}
{
const std::string fp = join(path, "sizeBytes");
const auto it = j.find("sizeBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.sizeBytes = std::move(val);
}
}
{
const std::string fp = join(path, "effectiveUrl");
const auto it = j.find("effectiveUrl");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.effectiveUrl = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const DownloadRemoveParams& v) {
j = nlohmann::json::object();
j["taskIds"] = v.taskIds;
j["deleteFile"] = v.deleteFile;
}
template <> Result<DownloadRemoveParams> parse<DownloadRemoveParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadRemoveParams out;
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
if (val.size() < 1u) return std::unexpected(ParseError{std::string(fp), "fewer than 1 items"});
if (val.size() > 5000u) return std::unexpected(ParseError{std::string(fp), "more than 5000 items"});
out.taskIds = std::move(val);
}
{
const std::string fp = join(path, "deleteFile");
const auto it = j.find("deleteFile");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.deleteFile = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadRemoveResultFailedItem& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["code"] = v.code;
j["message"] = v.message;
}
template <> Result<DownloadRemoveResultFailedItem> parse<DownloadRemoveResultFailedItem>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadRemoveResultFailedItem out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "code");
const auto it = j.find("code");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<ErrorCode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.code = std::move(val);
}
{
const std::string fp = join(path, "message");
const auto it = j.find("message");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.message = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadRemoveResult& v) {
j = nlohmann::json::object();
j["removed"] = v.removed;
j["failed"] = v.failed;
}
template <> Result<DownloadRemoveResult> parse<DownloadRemoveResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadRemoveResult out;
{
const std::string fp = join(path, "removed");
const auto it = j.find("removed");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.removed = std::move(val);
}
{
const std::string fp = join(path, "failed");
const auto it = j.find("failed");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<DownloadRemoveResultFailedItem> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<DownloadRemoveResultFailedItem>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.failed = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadResumeParams& v) {
j = nlohmann::json::object();
j["taskIds"] = v.taskIds;
}
template <> Result<DownloadResumeParams> parse<DownloadResumeParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadResumeParams out;
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
if (val.size() < 1u) return std::unexpected(ParseError{std::string(fp), "fewer than 1 items"});
if (val.size() > 5000u) return std::unexpected(ParseError{std::string(fp), "more than 5000 items"});
out.taskIds = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadStartParams& v) {
j = nlohmann::json::object();
j["taskIds"] = v.taskIds;
}
template <> Result<DownloadStartParams> parse<DownloadStartParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadStartParams out;
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
if (val.size() < 1u) return std::unexpected(ParseError{std::string(fp), "fewer than 1 items"});
if (val.size() > 5000u) return std::unexpected(ParseError{std::string(fp), "more than 5000 items"});
out.taskIds = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const DownloadUpdateParamsPatch& v) {
j = nlohmann::json::object();
if (v.filename.has_value()) j["filename"] = *v.filename;
if (v.saveDir.has_value()) j["saveDir"] = *v.saveDir;
if (v.categoryId.has_value()) j["categoryId"] = *v.categoryId;
if (v.queueId.has_value()) j["queueId"] = *v.queueId;
if (v.description.has_value()) j["description"] = *v.description;
if (v.segments.has_value()) j["segments"] = *v.segments;
if (v.bufferBytes.has_value()) j["bufferBytes"] = *v.bufferBytes;
if (v.checksum.has_value()) j["checksum"] = *v.checksum;
}
template <> Result<DownloadUpdateParamsPatch> parse<DownloadUpdateParamsPatch>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadUpdateParamsPatch out;
{
const std::string fp = join(path, "filename");
const auto it = j.find("filename");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 255u) return std::unexpected(ParseError{std::string(fp), "value is longer than 255 characters"});
out.filename = std::move(val);
}
}
{
const std::string fp = join(path, "saveDir");
const auto it = j.find("saveDir");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.saveDir = std::move(val);
}
}
{
const std::string fp = join(path, "categoryId");
const auto it = j.find("categoryId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.categoryId = std::move(val);
}
}
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
}
{
const std::string fp = join(path, "description");
const auto it = j.find("description");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 1024u) return std::unexpected(ParseError{std::string(fp), "value is longer than 1024 characters"});
out.description = std::move(val);
}
}
{
const std::string fp = join(path, "segments");
const auto it = j.find("segments");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 32) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 32"});
out.segments = std::move(val);
}
}
{
const std::string fp = join(path, "bufferBytes");
const auto it = j.find("bufferBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 4096) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 4096"});
if (val > 8388608) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 8388608"});
out.bufferBytes = std::move(val);
}
}
{
const std::string fp = join(path, "checksum");
const auto it = j.find("checksum");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Checksum>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.checksum = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const DownloadUpdateParams& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["patch"] = v.patch;
}
template <> Result<DownloadUpdateParams> parse<DownloadUpdateParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
DownloadUpdateParams out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "patch");
const auto it = j.find("patch");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<DownloadUpdateParamsPatch>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.patch = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const GrabberHarvestParams& v) {
j = nlohmann::json::object();
j["jobId"] = v.jobId;
j["select"] = v.select;
if (v.defaults.has_value()) j["defaults"] = *v.defaults;
}
template <> Result<GrabberHarvestParams> parse<GrabberHarvestParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
GrabberHarvestParams out;
{
const std::string fp = join(path, "jobId");
const auto it = j.find("jobId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.jobId = std::move(val);
}
{
const std::string fp = join(path, "select");
const auto it = j.find("select");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
if (val.size() < 1u) return std::unexpected(ParseError{std::string(fp), "fewer than 1 items"});
out.select = std::move(val);
}
{
const std::string fp = join(path, "defaults");
const auto it = j.find("defaults");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<DownloadSpec>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.defaults = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const GrabberHarvestResultFailedItem& v) {
j = nlohmann::json::object();
j["fileId"] = v.fileId;
j["code"] = v.code;
j["message"] = v.message;
}
template <> Result<GrabberHarvestResultFailedItem> parse<GrabberHarvestResultFailedItem>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
GrabberHarvestResultFailedItem out;
{
const std::string fp = join(path, "fileId");
const auto it = j.find("fileId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.fileId = std::move(val);
}
{
const std::string fp = join(path, "code");
const auto it = j.find("code");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<ErrorCode>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.code = std::move(val);
}
{
const std::string fp = join(path, "message");
const auto it = j.find("message");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.message = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const GrabberHarvestResult& v) {
j = nlohmann::json::object();
j["taskIds"] = v.taskIds;
j["failed"] = v.failed;
}
template <> Result<GrabberHarvestResult> parse<GrabberHarvestResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
GrabberHarvestResult out;
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.taskIds = std::move(val);
}
{
const std::string fp = join(path, "failed");
const auto it = j.find("failed");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<GrabberHarvestResultFailedItem> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<GrabberHarvestResultFailedItem>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.failed = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const GrabberStartParams& v) {
j = nlohmann::json::object();
j["startUrl"] = v.startUrl;
j["depth"] = v.depth;
if (v.includePatterns.has_value()) j["includePatterns"] = *v.includePatterns;
if (v.excludePatterns.has_value()) j["excludePatterns"] = *v.excludePatterns;
if (v.fileTypes.has_value()) j["fileTypes"] = *v.fileTypes;
if (v.sameHostOnly.has_value()) j["sameHostOnly"] = *v.sameHostOnly;
if (v.maxFiles.has_value()) j["maxFiles"] = *v.maxFiles;
if (v.headers.has_value()) j["headers"] = *v.headers;
if (v.cookies.has_value()) j["cookies"] = *v.cookies;
}
template <> Result<GrabberStartParams> parse<GrabberStartParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
GrabberStartParams out;
{
const std::string fp = join(path, "startUrl");
const auto it = j.find("startUrl");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.startUrl = std::move(val);
}
{
const std::string fp = join(path, "depth");
const auto it = j.find("depth");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
if (val > 10) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 10"});
out.depth = std::move(val);
}
{
const std::string fp = join(path, "includePatterns");
const auto it = j.find("includePatterns");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.includePatterns = std::move(val);
}
}
{
const std::string fp = join(path, "excludePatterns");
const auto it = j.find("excludePatterns");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.excludePatterns = std::move(val);
}
}
{
const std::string fp = join(path, "fileTypes");
const auto it = j.find("fileTypes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.fileTypes = std::move(val);
}
}
{
const std::string fp = join(path, "sameHostOnly");
const auto it = j.find("sameHostOnly");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.sameHostOnly = std::move(val);
}
}
{
const std::string fp = join(path, "maxFiles");
const auto it = j.find("maxFiles");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"});
if (val > 10000) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 10000"});
out.maxFiles = std::move(val);
}
}
{
const std::string fp = join(path, "headers");
const auto it = j.find("headers");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Headers>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.headers = std::move(val);
}
}
{
const std::string fp = join(path, "cookies");
const auto it = j.find("cookies");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Cookie> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Cookie>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.cookies = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const GrabberStartResult& v) {
j = nlohmann::json::object();
j["jobId"] = v.jobId;
}
template <> Result<GrabberStartResult> parse<GrabberStartResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
GrabberStartResult out;
{
const std::string fp = join(path, "jobId");
const auto it = j.find("jobId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.jobId = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const GrabberStatusParams& v) {
j = nlohmann::json::object();
j["jobId"] = v.jobId;
}
template <> Result<GrabberStatusParams> parse<GrabberStatusParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
GrabberStatusParams out;
{
const std::string fp = join(path, "jobId");
const auto it = j.find("jobId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.jobId = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const GrabberStatusResult& v) {
j = nlohmann::json::object();
j["jobId"] = v.jobId;
j["state"] = v.state;
j["crawled"] = v.crawled;
j["found"] = v.found;
j["files"] = v.files;
if (v.error.has_value()) j["error"] = *v.error;
}
template <> Result<GrabberStatusResult> parse<GrabberStatusResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
GrabberStatusResult out;
{
const std::string fp = join(path, "jobId");
const auto it = j.find("jobId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.jobId = std::move(val);
}
{
const std::string fp = join(path, "state");
const auto it = j.find("state");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<GrabberStatusResultState>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.state = std::move(val);
}
{
const std::string fp = join(path, "crawled");
const auto it = j.find("crawled");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.crawled = std::move(val);
}
{
const std::string fp = join(path, "found");
const auto it = j.find("found");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.found = std::move(val);
}
{
const std::string fp = join(path, "files");
const auto it = j.find("files");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<GrabberFile> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<GrabberFile>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.files = std::move(val);
}
{
const std::string fp = join(path, "error");
const auto it = j.find("error");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.error = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const LimiterGetParams& /*v*/) {
j = nlohmann::json::object();
}
template <> Result<LimiterGetParams> parse<LimiterGetParams>(const nlohmann::json& j, std::string_view /*path*/) {
if (!j.is_object()) return std::unexpected(ParseError{"", "expected an object"});
LimiterGetParams out;
return out;
}
void to_json(nlohmann::json& j, const MediaAddVariantParams& v) {
j = nlohmann::json::object();
j["manifestUrl"] = v.manifestUrl;
j["variantId"] = v.variantId;
if (v.audioVariantId.has_value()) j["audioVariantId"] = *v.audioVariantId;
if (v.spec.has_value()) j["spec"] = *v.spec;
}
template <> Result<MediaAddVariantParams> parse<MediaAddVariantParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
MediaAddVariantParams out;
{
const std::string fp = join(path, "manifestUrl");
const auto it = j.find("manifestUrl");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.manifestUrl = std::move(val);
}
{
const std::string fp = join(path, "variantId");
const auto it = j.find("variantId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.variantId = std::move(val);
}
{
const std::string fp = join(path, "audioVariantId");
const auto it = j.find("audioVariantId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.audioVariantId = std::move(val);
}
}
{
const std::string fp = join(path, "spec");
const auto it = j.find("spec");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<DownloadSpec>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.spec = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const MediaAddVariantResult& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["state"] = v.state;
if (v.estimatedBytes.has_value()) j["estimatedBytes"] = *v.estimatedBytes;
}
template <> Result<MediaAddVariantResult> parse<MediaAddVariantResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
MediaAddVariantResult out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "state");
const auto it = j.find("state");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskState>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.state = std::move(val);
}
{
const std::string fp = join(path, "estimatedBytes");
const auto it = j.find("estimatedBytes");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.estimatedBytes = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const MediaListVariantsParams& v) {
j = nlohmann::json::object();
j["manifestUrl"] = v.manifestUrl;
if (v.headers.has_value()) j["headers"] = *v.headers;
if (v.cookies.has_value()) j["cookies"] = *v.cookies;
if (v.referrer.has_value()) j["referrer"] = *v.referrer;
}
template <> Result<MediaListVariantsParams> parse<MediaListVariantsParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
MediaListVariantsParams out;
{
const std::string fp = join(path, "manifestUrl");
const auto it = j.find("manifestUrl");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.manifestUrl = std::move(val);
}
{
const std::string fp = join(path, "headers");
const auto it = j.find("headers");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Headers>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.headers = std::move(val);
}
}
{
const std::string fp = join(path, "cookies");
const auto it = j.find("cookies");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Cookie> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Cookie>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.cookies = std::move(val);
}
}
{
const std::string fp = join(path, "referrer");
const auto it = j.find("referrer");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.referrer = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const MediaListVariantsResult& v) {
j = nlohmann::json::object();
j["variants"] = v.variants;
j["manifestType"] = v.manifestType;
if (v.durationSec.has_value()) j["durationSec"] = *v.durationSec;
if (v.title.has_value()) j["title"] = *v.title;
j["drmProtected"] = v.drmProtected;
}
template <> Result<MediaListVariantsResult> parse<MediaListVariantsResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
MediaListVariantsResult out;
{
const std::string fp = join(path, "variants");
const auto it = j.find("variants");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<MediaVariant> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<MediaVariant>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.variants = std::move(val);
}
{
const std::string fp = join(path, "manifestType");
const auto it = j.find("manifestType");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<MediaListVariantsResultManifestType>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.manifestType = std::move(val);
}
{
const std::string fp = join(path, "durationSec");
const auto it = j.find("durationSec");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number()) return std::unexpected(ParseError{std::string(fp), "expected a number"});
auto val = (*it).get<double>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.durationSec = std::move(val);
}
}
{
const std::string fp = join(path, "title");
const auto it = j.find("title");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.title = std::move(val);
}
}
{
const std::string fp = join(path, "drmProtected");
const auto it = j.find("drmProtected");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.drmProtected = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const QueueListParams& /*v*/) {
j = nlohmann::json::object();
}
template <> Result<QueueListParams> parse<QueueListParams>(const nlohmann::json& j, std::string_view /*path*/) {
if (!j.is_object()) return std::unexpected(ParseError{"", "expected an object"});
QueueListParams out;
return out;
}
void to_json(nlohmann::json& j, const QueueListResult& v) {
j = nlohmann::json::object();
j["items"] = v.items;
}
template <> Result<QueueListResult> parse<QueueListResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
QueueListResult out;
{
const std::string fp = join(path, "items");
const auto it = j.find("items");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Queue> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Queue>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.items = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const QueueReorderParams& v) {
j = nlohmann::json::object();
j["queueId"] = v.queueId;
j["taskIds"] = v.taskIds;
}
template <> Result<QueueReorderParams> parse<QueueReorderParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
QueueReorderParams out;
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.taskIds = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const QueueReorderResult& v) {
j = nlohmann::json::object();
j["queue"] = v.queue;
}
template <> Result<QueueReorderResult> parse<QueueReorderResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
QueueReorderResult out;
{
const std::string fp = join(path, "queue");
const auto it = j.find("queue");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Queue>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.queue = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const QueueStartParams& v) {
j = nlohmann::json::object();
j["queueId"] = v.queueId;
}
template <> Result<QueueStartParams> parse<QueueStartParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
QueueStartParams out;
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const QueueStartResult& v) {
j = nlohmann::json::object();
j["queue"] = v.queue;
j["startedTaskIds"] = v.startedTaskIds;
}
template <> Result<QueueStartResult> parse<QueueStartResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
QueueStartResult out;
{
const std::string fp = join(path, "queue");
const auto it = j.find("queue");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Queue>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.queue = std::move(val);
}
{
const std::string fp = join(path, "startedTaskIds");
const auto it = j.find("startedTaskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.startedTaskIds = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const QueueStopParams& v) {
j = nlohmann::json::object();
j["queueId"] = v.queueId;
if (v.pauseRunning.has_value()) j["pauseRunning"] = *v.pauseRunning;
}
template <> Result<QueueStopParams> parse<QueueStopParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
QueueStopParams out;
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
{
const std::string fp = join(path, "pauseRunning");
const auto it = j.find("pauseRunning");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.pauseRunning = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const QueueStopResult& v) {
j = nlohmann::json::object();
j["queue"] = v.queue;
j["pausedTaskIds"] = v.pausedTaskIds;
}
template <> Result<QueueStopResult> parse<QueueStopResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
QueueStopResult out;
{
const std::string fp = join(path, "queue");
const auto it = j.find("queue");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Queue>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.queue = std::move(val);
}
{
const std::string fp = join(path, "pausedTaskIds");
const auto it = j.find("pausedTaskIds");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.pausedTaskIds = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const QueueUpsertParams& v) {
j = nlohmann::json::object();
j["queue"] = v.queue;
}
template <> Result<QueueUpsertParams> parse<QueueUpsertParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
QueueUpsertParams out;
{
const std::string fp = join(path, "queue");
const auto it = j.find("queue");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Queue>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.queue = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const QueueUpsertResult& v) {
j = nlohmann::json::object();
j["queue"] = v.queue;
}
template <> Result<QueueUpsertResult> parse<QueueUpsertResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
QueueUpsertResult out;
{
const std::string fp = join(path, "queue");
const auto it = j.find("queue");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Queue>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.queue = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const RulesListParams& /*v*/) {
j = nlohmann::json::object();
}
template <> Result<RulesListParams> parse<RulesListParams>(const nlohmann::json& j, std::string_view /*path*/) {
if (!j.is_object()) return std::unexpected(ParseError{"", "expected an object"});
RulesListParams out;
return out;
}
void to_json(nlohmann::json& j, const RulesListResult& v) {
j = nlohmann::json::object();
j["items"] = v.items;
}
template <> Result<RulesListResult> parse<RulesListResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
RulesListResult out;
{
const std::string fp = join(path, "items");
const auto it = j.find("items");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Rule> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Rule>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.items = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const RulesUpsertParams& v) {
j = nlohmann::json::object();
j["upsert"] = v.upsert;
if (v.remove.has_value()) j["remove"] = *v.remove;
}
template <> Result<RulesUpsertParams> parse<RulesUpsertParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
RulesUpsertParams out;
{
const std::string fp = join(path, "upsert");
const auto it = j.find("upsert");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Rule> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Rule>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.upsert = std::move(val);
}
{
const std::string fp = join(path, "remove");
const auto it = j.find("remove");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.remove = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const RulesUpsertResult& v) {
j = nlohmann::json::object();
j["items"] = v.items;
}
template <> Result<RulesUpsertResult> parse<RulesUpsertResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
RulesUpsertResult out;
{
const std::string fp = join(path, "items");
const auto it = j.find("items");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<Rule> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<Rule>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.items = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const ScheduleGetParams& v) {
j = nlohmann::json::object();
if (v.queueId.has_value()) j["queueId"] = *v.queueId;
}
template <> Result<ScheduleGetParams> parse<ScheduleGetParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
ScheduleGetParams out;
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const ScheduleGetResultItemsItem& v) {
j = nlohmann::json::object();
j["queueId"] = v.queueId;
if (v.schedule.has_value()) j["schedule"] = *v.schedule;
else j["schedule"] = nullptr;
}
template <> Result<ScheduleGetResultItemsItem> parse<ScheduleGetResultItemsItem>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
ScheduleGetResultItemsItem out;
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
{
const std::string fp = join(path, "schedule");
const auto it = j.find("schedule");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Schedule>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.schedule = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const ScheduleGetResult& v) {
j = nlohmann::json::object();
j["items"] = v.items;
}
template <> Result<ScheduleGetResult> parse<ScheduleGetResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
ScheduleGetResult out;
{
const std::string fp = join(path, "items");
const auto it = j.find("items");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<ScheduleGetResultItemsItem> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<ScheduleGetResultItemsItem>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.items = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const ScheduleSetParams& v) {
j = nlohmann::json::object();
j["queueId"] = v.queueId;
if (v.schedule.has_value()) j["schedule"] = *v.schedule;
else j["schedule"] = nullptr;
}
template <> Result<ScheduleSetParams> parse<ScheduleSetParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
ScheduleSetParams out;
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
{
const std::string fp = join(path, "schedule");
const auto it = j.find("schedule");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Schedule>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.schedule = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const ScheduleSetResult& v) {
j = nlohmann::json::object();
j["queueId"] = v.queueId;
if (v.schedule.has_value()) j["schedule"] = *v.schedule;
else j["schedule"] = nullptr;
if (v.nextRunAt.has_value()) j["nextRunAt"] = *v.nextRunAt;
}
template <> Result<ScheduleSetResult> parse<ScheduleSetResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
ScheduleSetResult out;
{
const std::string fp = join(path, "queueId");
const auto it = j.find("queueId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.queueId = std::move(val);
}
{
const std::string fp = join(path, "schedule");
const auto it = j.find("schedule");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<Schedule>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.schedule = std::move(val);
}
}
{
const std::string fp = join(path, "nextRunAt");
const auto it = j.find("nextRunAt");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.nextRunAt = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const SessionHelloParams& v) {
j = nlohmann::json::object();
j["clientType"] = v.clientType;
j["clientName"] = v.clientName;
j["protocolVersion"] = v.protocolVersion;
if (v.token.has_value()) j["token"] = *v.token;
}
template <> Result<SessionHelloParams> parse<SessionHelloParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SessionHelloParams out;
{
const std::string fp = join(path, "clientType");
const auto it = j.find("clientType");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<SessionHelloParamsClientType>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.clientType = std::move(val);
}
{
const std::string fp = join(path, "clientName");
const auto it = j.find("clientName");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 64u) return std::unexpected(ParseError{std::string(fp), "value is longer than 64 characters"});
out.clientName = std::move(val);
}
{
const std::string fp = join(path, "protocolVersion");
const auto it = j.find("protocolVersion");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
{
static const std::regex re("^[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?$", std::regex::ECMAScript);
if (!std::regex_match(val, re)) return std::unexpected(ParseError{std::string(fp), "value does not match the required pattern"});
}
out.protocolVersion = std::move(val);
}
{
const std::string fp = join(path, "token");
const auto it = j.find("token");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.token = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const SessionHelloResult& v) {
j = nlohmann::json::object();
j["daemonVersion"] = v.daemonVersion;
j["protocolVersion"] = v.protocolVersion;
j["capabilities"] = v.capabilities;
j["sessionId"] = v.sessionId;
if (v.transport.has_value()) j["transport"] = *v.transport;
}
template <> Result<SessionHelloResult> parse<SessionHelloResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SessionHelloResult out;
{
const std::string fp = join(path, "daemonVersion");
const auto it = j.find("daemonVersion");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.daemonVersion = std::move(val);
}
{
const std::string fp = join(path, "protocolVersion");
const auto it = j.find("protocolVersion");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.protocolVersion = std::move(val);
}
{
const std::string fp = join(path, "capabilities");
const auto it = j.find("capabilities");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.capabilities = std::move(val);
}
{
const std::string fp = join(path, "sessionId");
const auto it = j.find("sessionId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.sessionId = std::move(val);
}
{
const std::string fp = join(path, "transport");
const auto it = j.find("transport");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<SessionHelloResultTransport>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.transport = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const SessionPairParams& v) {
j = nlohmann::json::object();
j["clientName"] = v.clientName;
j["extensionId"] = v.extensionId;
if (v.code.has_value()) j["code"] = *v.code;
}
template <> Result<SessionPairParams> parse<SessionPairParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SessionPairParams out;
{
const std::string fp = join(path, "clientName");
const auto it = j.find("clientName");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 64u) return std::unexpected(ParseError{std::string(fp), "value is longer than 64 characters"});
out.clientName = std::move(val);
}
{
const std::string fp = join(path, "extensionId");
const auto it = j.find("extensionId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.extensionId = std::move(val);
}
{
const std::string fp = join(path, "code");
const auto it = j.find("code");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
{
static const std::regex re("^[0-9]{4}$", std::regex::ECMAScript);
if (!std::regex_match(val, re)) return std::unexpected(ParseError{std::string(fp), "value does not match the required pattern"});
}
out.code = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const SessionPairResult& v) {
j = nlohmann::json::object();
j["token"] = v.token;
if (v.expiresAt.has_value()) j["expiresAt"] = *v.expiresAt;
else j["expiresAt"] = nullptr;
}
template <> Result<SessionPairResult> parse<SessionPairResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SessionPairResult out;
{
const std::string fp = join(path, "token");
const auto it = j.find("token");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() < 43u) return std::unexpected(ParseError{std::string(fp), "value is shorter than 43 characters"});
out.token = std::move(val);
}
{
const std::string fp = join(path, "expiresAt");
const auto it = j.find("expiresAt");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.expiresAt = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const SessionSubscribeParams& v) {
j = nlohmann::json::object();
j["events"] = v.events;
if (v.taskIds.has_value()) j["taskIds"] = *v.taskIds;
}
template <> Result<SessionSubscribeParams> parse<SessionSubscribeParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SessionSubscribeParams out;
{
const std::string fp = join(path, "events");
const auto it = j.find("events");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<SessionSubscribeParamsEventsItem> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<SessionSubscribeParamsEventsItem>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.events = std::move(val);
}
{
const std::string fp = join(path, "taskIds");
const auto it = j.find("taskIds");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.taskIds = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const SessionSubscribeResult& v) {
j = nlohmann::json::object();
j["ok"] = v.ok;
j["events"] = v.events;
}
template <> Result<SessionSubscribeResult> parse<SessionSubscribeResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SessionSubscribeResult out;
{
const std::string fp = join(path, "ok");
const auto it = j.find("ok");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.ok = std::move(val);
}
{
const std::string fp = join(path, "events");
const auto it = j.find("events");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<std::string> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
if (!(*it)[idx].is_string()) return std::unexpected(ParseError{std::string(ip), "expected a string"});
auto val_e = (*it)[idx].get<std::string>();
val.push_back(std::move(val_e));
}
out.events = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const SettingsGetParams& v) {
j = nlohmann::json::object();
if (v.keys.has_value()) j["keys"] = *v.keys;
}
template <> Result<SettingsGetParams> parse<SettingsGetParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SettingsGetParams out;
{
const std::string fp = join(path, "keys");
const auto it = j.find("keys");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<SettingKey> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<SettingKey>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.keys = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const SettingsGetResult& v) {
j = nlohmann::json::object();
j["values"] = v.values;
}
template <> Result<SettingsGetResult> parse<SettingsGetResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SettingsGetResult out;
{
const std::string fp = join(path, "values");
const auto it = j.find("values");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Settings>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.values = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const SettingsSetParams& v) {
j = nlohmann::json::object();
j["values"] = v.values;
}
template <> Result<SettingsSetParams> parse<SettingsSetParams>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SettingsSetParams out;
{
const std::string fp = join(path, "values");
const auto it = j.find("values");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Settings>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.values = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const SettingsSetResult& v) {
j = nlohmann::json::object();
j["values"] = v.values;
j["changed"] = v.changed;
}
template <> Result<SettingsSetResult> parse<SettingsSetResult>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SettingsSetResult out;
{
const std::string fp = join(path, "values");
const auto it = j.find("values");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<Settings>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.values = std::move(val);
}
{
const std::string fp = join(path, "changed");
const auto it = j.find("changed");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<SettingKey> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<SettingKey>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.changed = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const AuthRequiredEvent& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["host"] = v.host;
if (v.realm.has_value()) j["realm"] = *v.realm;
j["scheme"] = v.scheme;
}
template <> Result<AuthRequiredEvent> parse<AuthRequiredEvent>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
AuthRequiredEvent out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "host");
const auto it = j.find("host");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.host = std::move(val);
}
{
const std::string fp = join(path, "realm");
const auto it = j.find("realm");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.realm = std::move(val);
}
}
{
const std::string fp = join(path, "scheme");
const auto it = j.find("scheme");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<AuthRequiredEventScheme>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.scheme = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const GrabberProgressEvent& v) {
j = nlohmann::json::object();
j["jobId"] = v.jobId;
j["found"] = v.found;
j["crawled"] = v.crawled;
j["done"] = v.done;
if (v.currentUrl.has_value()) j["currentUrl"] = *v.currentUrl;
}
template <> Result<GrabberProgressEvent> parse<GrabberProgressEvent>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
GrabberProgressEvent out;
{
const std::string fp = join(path, "jobId");
const auto it = j.find("jobId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.jobId = std::move(val);
}
{
const std::string fp = join(path, "found");
const auto it = j.find("found");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.found = std::move(val);
}
{
const std::string fp = join(path, "crawled");
const auto it = j.find("crawled");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.crawled = std::move(val);
}
{
const std::string fp = join(path, "done");
const auto it = j.find("done");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.done = std::move(val);
}
{
const std::string fp = join(path, "currentUrl");
const auto it = j.find("currentUrl");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.currentUrl = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const NotifyEvent& v) {
j = nlohmann::json::object();
j["level"] = v.level;
j["title"] = v.title;
j["body"] = v.body;
if (v.taskId.has_value()) j["taskId"] = *v.taskId;
if (v.sound.has_value()) j["sound"] = *v.sound;
}
template <> Result<NotifyEvent> parse<NotifyEvent>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
NotifyEvent out;
{
const std::string fp = join(path, "level");
const auto it = j.find("level");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<NotifyEventLevel>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.level = std::move(val);
}
{
const std::string fp = join(path, "title");
const auto it = j.find("title");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 128u) return std::unexpected(ParseError{std::string(fp), "value is longer than 128 characters"});
out.title = std::move(val);
}
{
const std::string fp = join(path, "body");
const auto it = j.find("body");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
if (val.size() > 1024u) return std::unexpected(ParseError{std::string(fp), "value is longer than 1024 characters"});
out.body = std::move(val);
}
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
}
{
const std::string fp = join(path, "sound");
const auto it = j.find("sound");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<NotifyEventSound>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.sound = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const SettingsChangedEvent& v) {
j = nlohmann::json::object();
j["keys"] = v.keys;
}
template <> Result<SettingsChangedEvent> parse<SettingsChangedEvent>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SettingsChangedEvent out;
{
const std::string fp = join(path, "keys");
const auto it = j.find("keys");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<SettingKey> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<SettingKey>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.keys = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const SpeedGlobalEvent& v) {
j = nlohmann::json::object();
j["downBps"] = v.downBps;
j["activeCount"] = v.activeCount;
if (v.queuedCount.has_value()) j["queuedCount"] = *v.queuedCount;
if (v.limitBps.has_value()) j["limitBps"] = *v.limitBps;
}
template <> Result<SpeedGlobalEvent> parse<SpeedGlobalEvent>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
SpeedGlobalEvent out;
{
const std::string fp = join(path, "downBps");
const auto it = j.find("downBps");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.downBps = std::move(val);
}
{
const std::string fp = join(path, "activeCount");
const auto it = j.find("activeCount");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.activeCount = std::move(val);
}
{
const std::string fp = join(path, "queuedCount");
const auto it = j.find("queuedCount");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.queuedCount = std::move(val);
}
}
{
const std::string fp = join(path, "limitBps");
const auto it = j.find("limitBps");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.limitBps = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const TaskAddedEvent& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["summary"] = v.summary;
}
template <> Result<TaskAddedEvent> parse<TaskAddedEvent>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskAddedEvent out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "summary");
const auto it = j.find("summary");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskSummary>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.summary = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const TaskProgressEventTasksItemSegmentsItem& v) {
j = nlohmann::json::object();
j["index"] = v.index;
j["downloadedBytes"] = v.downloadedBytes;
j["speedBps"] = v.speedBps;
}
template <> Result<TaskProgressEventTasksItemSegmentsItem> parse<TaskProgressEventTasksItemSegmentsItem>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskProgressEventTasksItemSegmentsItem out;
{
const std::string fp = join(path, "index");
const auto it = j.find("index");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
if (val > 31) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 31"});
out.index = std::move(val);
}
{
const std::string fp = join(path, "downloadedBytes");
const auto it = j.find("downloadedBytes");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.downloadedBytes = std::move(val);
}
{
const std::string fp = join(path, "speedBps");
const auto it = j.find("speedBps");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.speedBps = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const TaskProgressEventTasksItem& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["downloadedBytes"] = v.downloadedBytes;
j["speedBps"] = v.speedBps;
if (v.etaSeconds.has_value()) j["etaSeconds"] = *v.etaSeconds;
if (v.segments.has_value()) j["segments"] = *v.segments;
}
template <> Result<TaskProgressEventTasksItem> parse<TaskProgressEventTasksItem>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskProgressEventTasksItem out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "downloadedBytes");
const auto it = j.find("downloadedBytes");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.downloadedBytes = std::move(val);
}
{
const std::string fp = join(path, "speedBps");
const auto it = j.find("speedBps");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.speedBps = std::move(val);
}
{
const std::string fp = join(path, "etaSeconds");
const auto it = j.find("etaSeconds");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_number_integer()) return std::unexpected(ParseError{std::string(fp), "expected an integer"});
auto val = (*it).get<std::int64_t>();
if (val < 0) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 0"});
out.etaSeconds = std::move(val);
}
}
{
const std::string fp = join(path, "segments");
const auto it = j.find("segments");
if (it != j.end() && !it->is_null()) {
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<TaskProgressEventTasksItemSegmentsItem> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<TaskProgressEventTasksItemSegmentsItem>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
if (val.size() > 32u) return std::unexpected(ParseError{std::string(fp), "more than 32 items"});
out.segments = std::move(val);
}
}
return out;
}
void to_json(nlohmann::json& j, const TaskProgressEvent& v) {
j = nlohmann::json::object();
j["tasks"] = v.tasks;
j["at"] = v.at;
}
template <> Result<TaskProgressEvent> parse<TaskProgressEvent>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskProgressEvent out;
{
const std::string fp = join(path, "tasks");
const auto it = j.find("tasks");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_array()) return std::unexpected(ParseError{std::string(fp), "expected an array"});
std::vector<TaskProgressEventTasksItem> val;
val.reserve((*it).size());
for (std::size_t idx = 0; idx < (*it).size(); ++idx) {
const std::string ip = join(fp, std::to_string(idx));
auto val_e_r = parse<TaskProgressEventTasksItem>((*it)[idx], ip);
if (!val_e_r) return std::unexpected(val_e_r.error());
auto val_e = std::move(*val_e_r);
val.push_back(std::move(val_e));
}
out.tasks = std::move(val);
}
{
const std::string fp = join(path, "at");
const auto it = j.find("at");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.at = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const TaskRemovedEvent& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["deletedFile"] = v.deletedFile;
}
template <> Result<TaskRemovedEvent> parse<TaskRemovedEvent>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskRemovedEvent out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "deletedFile");
const auto it = j.find("deletedFile");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_boolean()) return std::unexpected(ParseError{std::string(fp), "expected a boolean"});
auto val = (*it).get<bool>();
out.deletedFile = std::move(val);
}
return out;
}
void to_json(nlohmann::json& j, const TaskStateEvent& v) {
j = nlohmann::json::object();
j["taskId"] = v.taskId;
j["state"] = v.state;
if (v.previousState.has_value()) j["previousState"] = *v.previousState;
if (v.summary.has_value()) j["summary"] = *v.summary;
if (v.error.has_value()) j["error"] = *v.error;
}
template <> Result<TaskStateEvent> parse<TaskStateEvent>(const nlohmann::json& j, std::string_view path) {
if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"});
TaskStateEvent out;
{
const std::string fp = join(path, "taskId");
const auto it = j.find("taskId");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
if (!(*it).is_string()) return std::unexpected(ParseError{std::string(fp), "expected a string"});
auto val = (*it).get<std::string>();
out.taskId = std::move(val);
}
{
const std::string fp = join(path, "state");
const auto it = j.find("state");
if (it == j.end() || it->is_null())
return std::unexpected(ParseError{fp, "required field is missing"});
auto val_r = parse<TaskState>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.state = std::move(val);
}
{
const std::string fp = join(path, "previousState");
const auto it = j.find("previousState");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<TaskState>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.previousState = std::move(val);
}
}
{
const std::string fp = join(path, "summary");
const auto it = j.find("summary");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<TaskSummary>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.summary = std::move(val);
}
}
{
const std::string fp = join(path, "error");
const auto it = j.find("error");
if (it != j.end() && !it->is_null()) {
auto val_r = parse<TaskError>((*it), fp);
if (!val_r) return std::unexpected(val_r.error());
auto val = std::move(*val_r);
out.error = std::move(val);
}
}
return out;
}
std::string_view to_string(Method m) noexcept {
switch (m) {
case Method::CaptureGetRules: return "capture.getRules";
case Method::CaptureOffer: return "capture.offer";
case Method::CategoryList: return "category.list";
case Method::CategoryRemove: return "category.remove";
case Method::CategoryUpsert: return "category.upsert";
case Method::DownloadAdd: return "download.add";
case Method::DownloadAddBatch: return "download.addBatch";
case Method::DownloadCancel: return "download.cancel";
case Method::DownloadGet: return "download.get";
case Method::DownloadList: return "download.list";
case Method::DownloadPause: return "download.pause";
case Method::DownloadProbe: return "download.probe";
case Method::DownloadRefreshUrl: return "download.refreshUrl";
case Method::DownloadRemove: return "download.remove";
case Method::DownloadResume: return "download.resume";
case Method::DownloadStart: return "download.start";
case Method::DownloadUpdate: return "download.update";
case Method::GrabberHarvest: return "grabber.harvest";
case Method::GrabberStart: return "grabber.start";
case Method::GrabberStatus: return "grabber.status";
case Method::LimiterGet: return "limiter.get";
case Method::LimiterSet: return "limiter.set";
case Method::MediaAddVariant: return "media.addVariant";
case Method::MediaListVariants: return "media.listVariants";
case Method::QueueList: return "queue.list";
case Method::QueueReorder: return "queue.reorder";
case Method::QueueStart: return "queue.start";
case Method::QueueStop: return "queue.stop";
case Method::QueueUpsert: return "queue.upsert";
case Method::RulesList: return "rules.list";
case Method::RulesUpsert: return "rules.upsert";
case Method::ScheduleGet: return "schedule.get";
case Method::ScheduleSet: return "schedule.set";
case Method::SessionHello: return "session.hello";
case Method::SessionPair: return "session.pair";
case Method::SessionSubscribe: return "session.subscribe";
case Method::SettingsGet: return "settings.get";
case Method::SettingsSet: return "settings.set";
}
return "";
}
std::optional<Method> method_from_string(std::string_view s) noexcept {
if (s == "capture.getRules") return Method::CaptureGetRules;
if (s == "capture.offer") return Method::CaptureOffer;
if (s == "category.list") return Method::CategoryList;
if (s == "category.remove") return Method::CategoryRemove;
if (s == "category.upsert") return Method::CategoryUpsert;
if (s == "download.add") return Method::DownloadAdd;
if (s == "download.addBatch") return Method::DownloadAddBatch;
if (s == "download.cancel") return Method::DownloadCancel;
if (s == "download.get") return Method::DownloadGet;
if (s == "download.list") return Method::DownloadList;
if (s == "download.pause") return Method::DownloadPause;
if (s == "download.probe") return Method::DownloadProbe;
if (s == "download.refreshUrl") return Method::DownloadRefreshUrl;
if (s == "download.remove") return Method::DownloadRemove;
if (s == "download.resume") return Method::DownloadResume;
if (s == "download.start") return Method::DownloadStart;
if (s == "download.update") return Method::DownloadUpdate;
if (s == "grabber.harvest") return Method::GrabberHarvest;
if (s == "grabber.start") return Method::GrabberStart;
if (s == "grabber.status") return Method::GrabberStatus;
if (s == "limiter.get") return Method::LimiterGet;
if (s == "limiter.set") return Method::LimiterSet;
if (s == "media.addVariant") return Method::MediaAddVariant;
if (s == "media.listVariants") return Method::MediaListVariants;
if (s == "queue.list") return Method::QueueList;
if (s == "queue.reorder") return Method::QueueReorder;
if (s == "queue.start") return Method::QueueStart;
if (s == "queue.stop") return Method::QueueStop;
if (s == "queue.upsert") return Method::QueueUpsert;
if (s == "rules.list") return Method::RulesList;
if (s == "rules.upsert") return Method::RulesUpsert;
if (s == "schedule.get") return Method::ScheduleGet;
if (s == "schedule.set") return Method::ScheduleSet;
if (s == "session.hello") return Method::SessionHello;
if (s == "session.pair") return Method::SessionPair;
if (s == "session.subscribe") return Method::SessionSubscribe;
if (s == "settings.get") return Method::SettingsGet;
if (s == "settings.set") return Method::SettingsSet;
return std::nullopt;
}
bool is_privileged(Method m) noexcept {
switch (m) {
case Method::CaptureGetRules: return false;
case Method::CaptureOffer: return false;
case Method::CategoryList: return false;
case Method::CategoryRemove: return true;
case Method::CategoryUpsert: return true;
case Method::DownloadAdd: return false;
case Method::DownloadAddBatch: return false;
case Method::DownloadCancel: return false;
case Method::DownloadGet: return false;
case Method::DownloadList: return false;
case Method::DownloadPause: return false;
case Method::DownloadProbe: return false;
case Method::DownloadRefreshUrl: return false;
case Method::DownloadRemove: return true;
case Method::DownloadResume: return false;
case Method::DownloadStart: return false;
case Method::DownloadUpdate: return true;
case Method::GrabberHarvest: return true;
case Method::GrabberStart: return true;
case Method::GrabberStatus: return true;
case Method::LimiterGet: return true;
case Method::LimiterSet: return true;
case Method::MediaAddVariant: return false;
case Method::MediaListVariants: return false;
case Method::QueueList: return false;
case Method::QueueReorder: return true;
case Method::QueueStart: return true;
case Method::QueueStop: return true;
case Method::QueueUpsert: return true;
case Method::RulesList: return true;
case Method::RulesUpsert: return true;
case Method::ScheduleGet: return true;
case Method::ScheduleSet: return true;
case Method::SessionHello: return false;
case Method::SessionPair: return false;
case Method::SessionSubscribe: return false;
case Method::SettingsGet: return true;
case Method::SettingsSet: return true;
}
return true; // unknown means refuse
}
bool is_allowed_on(Method m, Transport t) noexcept {
switch (m) {
case Method::CaptureGetRules: return t == Transport::Uds ? true : true;
case Method::CaptureOffer: return t == Transport::Uds ? true : true;
case Method::CategoryList: return t == Transport::Uds ? true : true;
case Method::CategoryRemove: return t == Transport::Uds ? true : false;
case Method::CategoryUpsert: return t == Transport::Uds ? true : false;
case Method::DownloadAdd: return t == Transport::Uds ? true : true;
case Method::DownloadAddBatch: return t == Transport::Uds ? true : true;
case Method::DownloadCancel: return t == Transport::Uds ? true : true;
case Method::DownloadGet: return t == Transport::Uds ? true : true;
case Method::DownloadList: return t == Transport::Uds ? true : true;
case Method::DownloadPause: return t == Transport::Uds ? true : true;
case Method::DownloadProbe: return t == Transport::Uds ? true : true;
case Method::DownloadRefreshUrl: return t == Transport::Uds ? true : true;
case Method::DownloadRemove: return t == Transport::Uds ? true : false;
case Method::DownloadResume: return t == Transport::Uds ? true : true;
case Method::DownloadStart: return t == Transport::Uds ? true : true;
case Method::DownloadUpdate: return t == Transport::Uds ? true : false;
case Method::GrabberHarvest: return t == Transport::Uds ? true : false;
case Method::GrabberStart: return t == Transport::Uds ? true : false;
case Method::GrabberStatus: return t == Transport::Uds ? true : false;
case Method::LimiterGet: return t == Transport::Uds ? true : false;
case Method::LimiterSet: return t == Transport::Uds ? true : false;
case Method::MediaAddVariant: return t == Transport::Uds ? true : true;
case Method::MediaListVariants: return t == Transport::Uds ? true : true;
case Method::QueueList: return t == Transport::Uds ? true : true;
case Method::QueueReorder: return t == Transport::Uds ? true : false;
case Method::QueueStart: return t == Transport::Uds ? true : false;
case Method::QueueStop: return t == Transport::Uds ? true : false;
case Method::QueueUpsert: return t == Transport::Uds ? true : false;
case Method::RulesList: return t == Transport::Uds ? true : false;
case Method::RulesUpsert: return t == Transport::Uds ? true : false;
case Method::ScheduleGet: return t == Transport::Uds ? true : false;
case Method::ScheduleSet: return t == Transport::Uds ? true : false;
case Method::SessionHello: return t == Transport::Uds ? true : true;
case Method::SessionPair: return t == Transport::Uds ? false : true;
case Method::SessionSubscribe: return t == Transport::Uds ? true : true;
case Method::SettingsGet: return t == Transport::Uds ? true : false;
case Method::SettingsSet: return t == Transport::Uds ? true : false;
}
return false;
}
std::int32_t deadline_ms(Method m) noexcept {
switch (m) {
case Method::CaptureGetRules: return 2000;
case Method::CaptureOffer: return 750;
case Method::CategoryList: return 2000;
case Method::CategoryRemove: return 5000;
case Method::CategoryUpsert: return 5000;
case Method::DownloadAdd: return 5000;
case Method::DownloadAddBatch: return 30000;
case Method::DownloadCancel: return 5000;
case Method::DownloadGet: return 5000;
case Method::DownloadList: return 5000;
case Method::DownloadPause: return 5000;
case Method::DownloadProbe: return 30000;
case Method::DownloadRefreshUrl: return 30000;
case Method::DownloadRemove: return 10000;
case Method::DownloadResume: return 5000;
case Method::DownloadStart: return 5000;
case Method::DownloadUpdate: return 30000;
case Method::GrabberHarvest: return 30000;
case Method::GrabberStart: return 5000;
case Method::GrabberStatus: return 5000;
case Method::LimiterGet: return 2000;
case Method::LimiterSet: return 5000;
case Method::MediaAddVariant: return 30000;
case Method::MediaListVariants: return 30000;
case Method::QueueList: return 2000;
case Method::QueueReorder: return 5000;
case Method::QueueStart: return 5000;
case Method::QueueStop: return 5000;
case Method::QueueUpsert: return 5000;
case Method::RulesList: return 2000;
case Method::RulesUpsert: return 5000;
case Method::ScheduleGet: return 2000;
case Method::ScheduleSet: return 5000;
case Method::SessionHello: return 2000;
case Method::SessionPair: return 120000;
case Method::SessionSubscribe: return 2000;
case Method::SettingsGet: return 2000;
case Method::SettingsSet: return 5000;
}
return 5000;
}
std::string_view to_string(Event e) noexcept {
switch (e) {
case Event::AuthRequired: return "event.auth.required";
case Event::GrabberProgress: return "event.grabber.progress";
case Event::Notify: return "event.notify";
case Event::SettingsChanged: return "event.settings.changed";
case Event::SpeedGlobal: return "event.speed.global";
case Event::TaskAdded: return "event.task.added";
case Event::TaskProgress: return "event.task.progress";
case Event::TaskRemoved: return "event.task.removed";
case Event::TaskState: return "event.task.state";
}
return "";
}
std::optional<Event> event_from_string(std::string_view s) noexcept {
if (s == "event.auth.required") return Event::AuthRequired;
if (s == "event.grabber.progress") return Event::GrabberProgress;
if (s == "event.notify") return Event::Notify;
if (s == "event.settings.changed") return Event::SettingsChanged;
if (s == "event.speed.global") return Event::SpeedGlobal;
if (s == "event.task.added") return Event::TaskAdded;
if (s == "event.task.progress") return Event::TaskProgress;
if (s == "event.task.removed") return Event::TaskRemoved;
if (s == "event.task.state") return Event::TaskState;
return std::nullopt;
}
nlohmann::json make_error(const nlohmann::json& id, ErrorCode code, std::string_view message,
nlohmann::json data) {
nlohmann::json err = {{"code", static_cast<std::int32_t>(code)}, {"message", std::string(message)}};
if (!data.is_null()) err["data"] = std::move(data);
return {{"jsonrpc", "2.0"}, {"id", id}, {"error", std::move(err)}};
}
nlohmann::json make_result(const nlohmann::json& id, nlohmann::json result) {
return {{"jsonrpc", "2.0"}, {"id", id}, {"result", std::move(result)}};
}
nlohmann::json make_notification(Event e, nlohmann::json params) {
return {{"jsonrpc", "2.0"}, {"method", std::string(to_string(e))}, {"params", std::move(params)}};
}
nlohmann::json dispatch(Dispatcher& handler, Transport transport, const nlohmann::json& request) {
const nlohmann::json id = request.contains("id") ? request.at("id") : nlohmann::json(nullptr);
if (!request.is_object() || request.value("jsonrpc", "") != "2.0" || !request.contains("method"))
return make_error(id, ErrorCode::InvalidRequest, "not a JSON-RPC 2.0 request");
if (!request.at("method").is_string())
return make_error(id, ErrorCode::InvalidRequest, "method must be a string");
const auto method = method_from_string(request.at("method").get_ref<const std::string&>());
if (!method)
return make_error(id, ErrorCode::MethodNotFound, "no such method");
if (!is_allowed_on(*method, transport))
return make_error(id, ErrorCode::TransportForbidden,
"method is not permitted on this transport");
const nlohmann::json params =
request.contains("params") ? request.at("params") : nlohmann::json::object();
switch (*method) {
case Method::CaptureGetRules: {
auto p = parse<CaptureGetRulesParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_capture_getRules(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::CaptureOffer: {
auto p = parse<CaptureOfferParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_capture_offer(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::CategoryList: {
auto p = parse<CategoryListParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_category_list(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::CategoryRemove: {
auto p = parse<CategoryRemoveParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_category_remove(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::CategoryUpsert: {
auto p = parse<CategoryUpsertParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_category_upsert(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadAdd: {
auto p = parse<DownloadSpec>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_add(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadAddBatch: {
auto p = parse<DownloadAddBatchParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_addBatch(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadCancel: {
auto p = parse<DownloadCancelParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_cancel(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadGet: {
auto p = parse<DownloadGetParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_get(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadList: {
auto p = parse<DownloadListParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_list(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadPause: {
auto p = parse<DownloadPauseParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_pause(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadProbe: {
auto p = parse<DownloadProbeParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_probe(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadRefreshUrl: {
auto p = parse<DownloadRefreshUrlParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_refreshUrl(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadRemove: {
auto p = parse<DownloadRemoveParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_remove(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadResume: {
auto p = parse<DownloadResumeParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_resume(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadStart: {
auto p = parse<DownloadStartParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_start(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::DownloadUpdate: {
auto p = parse<DownloadUpdateParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_download_update(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::GrabberHarvest: {
auto p = parse<GrabberHarvestParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_grabber_harvest(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::GrabberStart: {
auto p = parse<GrabberStartParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_grabber_start(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::GrabberStatus: {
auto p = parse<GrabberStatusParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_grabber_status(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::LimiterGet: {
auto p = parse<LimiterGetParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_limiter_get(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::LimiterSet: {
auto p = parse<Limiter>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_limiter_set(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::MediaAddVariant: {
auto p = parse<MediaAddVariantParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_media_addVariant(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::MediaListVariants: {
auto p = parse<MediaListVariantsParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_media_listVariants(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::QueueList: {
auto p = parse<QueueListParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_queue_list(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::QueueReorder: {
auto p = parse<QueueReorderParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_queue_reorder(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::QueueStart: {
auto p = parse<QueueStartParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_queue_start(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::QueueStop: {
auto p = parse<QueueStopParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_queue_stop(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::QueueUpsert: {
auto p = parse<QueueUpsertParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_queue_upsert(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::RulesList: {
auto p = parse<RulesListParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_rules_list(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::RulesUpsert: {
auto p = parse<RulesUpsertParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_rules_upsert(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::ScheduleGet: {
auto p = parse<ScheduleGetParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_schedule_get(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::ScheduleSet: {
auto p = parse<ScheduleSetParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_schedule_set(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::SessionHello: {
auto p = parse<SessionHelloParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_session_hello(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::SessionPair: {
auto p = parse<SessionPairParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_session_pair(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::SessionSubscribe: {
auto p = parse<SessionSubscribeParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_session_subscribe(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::SettingsGet: {
auto p = parse<SettingsGetParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_settings_get(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
case Method::SettingsSet: {
auto p = parse<SettingsSetParams>(params, "params");
if (!p)
return make_error(id, ErrorCode::InvalidParams, p.error().message,
nlohmann::json{{"path", p.error().path}});
auto r = handler.on_settings_set(*p);
if (!r)
return make_error(id, ErrorCode::InternalError, r.error().message,
nlohmann::json{{"path", r.error().path}});
nlohmann::json out = *r;
return make_result(id, std::move(out));
}
}
return make_error(id, ErrorCode::MethodNotFound, "no such method");
}
} // namespace velox::proto