// --------------------------------------------------------------------------- // GENERATED FILE — DO NOT EDIT. // // Source: contracts/schema/** // Generator: contracts/codegen/gen_cpp.py // Contract: v1.4.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 #include 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_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(v); } template <> Result parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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::ConnectionMaxTotalBufferBytes: return "connection.maxTotalBufferBytes"; case SettingKey::ConnectionMaxActiveSegments: return "connection.maxActiveSegments"; 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 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.maxTotalBufferBytes") return SettingKey::ConnectionMaxTotalBufferBytes; if (s == "connection.maxActiveSegments") return SettingKey::ConnectionMaxActiveSegments; 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); 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 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 parse(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()); if (!r) return std::unexpected(ParseError{std::string(path), r.error().message}); return *r; } template <> Result parse(const nlohmann::json& j, std::string_view path) { if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"}); std::map 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(); 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 parse(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(); 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((*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(); 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 parse(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(); 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((*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(); 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 parse(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 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((*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 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((*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 parse(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(); 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 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(); 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 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(); 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(); 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 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(); 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((*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(); 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 parse(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(); 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(); 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(); 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 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(); { 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 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(); 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(); 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(); 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 parse(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((*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(); { 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 parse(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(); 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(); 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(); 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(); 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(); 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(); 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 parse(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(); 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((*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 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((*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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); if (val < 65536) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 65536"}); if (val > 16777216) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 16777216"}); 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((*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(); 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((*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 parse(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(); 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(); 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(); 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(); 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(); 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(); 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(); 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 parse(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(); 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(); 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(); 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 parse(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(); 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((*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(); { 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(); 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(); 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((*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(); 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(); 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(); 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(); 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 parse(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(); 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((*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(); { 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(); { 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 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(); 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(); 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 parse(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(); 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(); 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((*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(); 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 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(); 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((*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((*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 parse(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(); 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(); 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(); 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(); 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((*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((*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 parse(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 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(); 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 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(); 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(); 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(); 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(); 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(); 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 parse(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(); 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(); 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(); 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(); 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((*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((*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 parse(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(); 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(); 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(); 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(); 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(); 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((*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(); 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; if (v.connection_maxTotalBufferBytes.has_value()) j["connection.maxTotalBufferBytes"] = *v.connection_maxTotalBufferBytes; if (v.connection_maxActiveSegments.has_value()) j["connection.maxActiveSegments"] = *v.connection_maxActiveSegments; } template <> Result parse(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(); 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(); 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(); 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(); 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(); 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(); 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(); 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 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(); 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 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(); 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(); 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 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(); 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((*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 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(); 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(); 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(); 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 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(); 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((*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(); 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((*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(); 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(); if (val < 65536) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 65536"}); if (val > 16777216) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 16777216"}); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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((*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(); 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((*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(); 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(); 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(); 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 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(); 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(); 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(); 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(); 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(); 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(); out.sounds_onError = std::move(val); } } { const std::string fp = join(path, "connection.maxTotalBufferBytes"); const auto it = j.find("connection.maxTotalBufferBytes"); 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(); if (val < 16777216) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 16777216"}); if (val > 2147483648) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 2147483648"}); out.connection_maxTotalBufferBytes = std::move(val); } } { const std::string fp = join(path, "connection.maxActiveSegments"); const auto it = j.find("connection.maxActiveSegments"); 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(); if (val < 1) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 1"}); if (val > 256) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 256"}); out.connection_maxActiveSegments = 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 parse(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((*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(); 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(); 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(); 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((*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(); 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(); 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 parse(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(); 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(); 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(); 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(); 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(); 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(); 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(); 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((*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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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((*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.effectiveBufferBytes.has_value()) j["effectiveBufferBytes"] = *v.effectiveBufferBytes; 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 parse(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((*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 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((*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((*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(); 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(); 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(); 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(); if (val < 65536) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 65536"}); if (val > 16777216) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 16777216"}); out.bufferBytes = std::move(val); } } { const std::string fp = join(path, "effectiveBufferBytes"); const auto it = j.find("effectiveBufferBytes"); 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(); if (val < 65536) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 65536"}); if (val > 16777216) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 16777216"}); out.effectiveBufferBytes = 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(); 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((*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(); 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(); 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(); 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 parse(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 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((*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(); 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(); 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(); 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(); 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(); 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 parse(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((*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((*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 parse(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 parse(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(); 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((*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(); 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((*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 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((*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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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 parse(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((*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(); 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((*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 parse(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 parse(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 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((*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 parse(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(); 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(); 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 parse(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(); 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 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(); 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 parse(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((*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 parse(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((*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 parse(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(); 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((*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(); 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 parse(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 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((*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((*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 parse(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(); 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((*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(); 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 parse(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 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(); 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 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((*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 parse(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 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(); 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 parse(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(); 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 parse(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((*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((*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(); 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(); 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 parse(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(); 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 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((*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 parse(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 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(); 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 parse(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(); 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((*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 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((*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(); 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(); 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 parse(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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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 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(); 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(); out.requiresAuth = std::move(val); } } return out; } void to_json(nlohmann::json& j, const DownloadProvideAuthParams& v) { j = nlohmann::json::object(); j["taskId"] = v.taskId; j["username"] = v.username; j["password"] = v.password; if (v.save.has_value()) j["save"] = *v.save; } template <> Result parse(const nlohmann::json& j, std::string_view path) { if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"}); DownloadProvideAuthParams 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(); out.taskId = std::move(val); } { const std::string fp = join(path, "username"); const auto it = j.find("username"); 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(); if (val.size() > 256u) return std::unexpected(ParseError{std::string(fp), "value is longer than 256 characters"}); out.username = std::move(val); } { const std::string fp = join(path, "password"); const auto it = j.find("password"); 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(); if (val.size() > 1024u) return std::unexpected(ParseError{std::string(fp), "value is longer than 1024 characters"}); out.password = std::move(val); } { const std::string fp = join(path, "save"); const auto it = j.find("save"); 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(); out.save = std::move(val); } } return out; } void to_json(nlohmann::json& j, const DownloadProvideAuthResult& v) { j = nlohmann::json::object(); j["ok"] = v.ok; } template <> Result parse(const nlohmann::json& j, std::string_view path) { if (!j.is_object()) return std::unexpected(ParseError{std::string(path), "expected an object"}); DownloadProvideAuthResult 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(); out.ok = 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 parse(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(); 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(); 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((*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 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((*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 parse(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(); 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(); 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(); 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(); 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(); 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 parse(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 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(); 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(); 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 parse(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(); 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((*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(); 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 parse(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 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(); 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 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((*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 parse(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 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(); 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 parse(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 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(); 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 parse(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(); 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(); 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(); 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(); 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(); 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(); 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(); if (val < 65536) return std::unexpected(ParseError{std::string(fp), "value is below the minimum of 65536"}); if (val > 16777216) return std::unexpected(ParseError{std::string(fp), "value is above the maximum of 16777216"}); 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((*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 parse(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(); 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((*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 parse(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(); 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 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(); 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((*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 parse(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(); 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((*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(); 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 parse(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 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(); 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 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((*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 parse(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(); 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(); 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 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(); 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 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(); 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 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(); 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(); 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(); 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((*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 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((*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 parse(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(); 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 parse(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(); 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 parse(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(); 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((*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(); 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(); 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 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((*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(); out.error = std::move(val); } } return out; } void to_json(nlohmann::json& j, const LimiterGetParams& /*v*/) { j = nlohmann::json::object(); } template <> Result parse(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 parse(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(); 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(); 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(); 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((*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 parse(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(); 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((*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(); 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 parse(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(); 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((*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 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((*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(); 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 parse(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 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((*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((*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(); 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(); 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(); out.drmProtected = std::move(val); } return out; } void to_json(nlohmann::json& j, const QueueListParams& /*v*/) { j = nlohmann::json::object(); } template <> Result parse(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 parse(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 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((*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 parse(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(); 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 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(); 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 parse(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((*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 parse(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(); 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 parse(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((*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 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(); 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 parse(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(); 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(); 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 parse(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((*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 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(); 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 parse(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((*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 parse(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((*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 parse(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 parse(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 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((*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 parse(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 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((*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 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(); 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 parse(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 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((*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 parse(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(); 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 parse(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(); 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((*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 parse(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 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((*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 parse(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(); 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((*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 parse(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(); 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((*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(); 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 parse(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((*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(); 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(); { 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(); 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 parse(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(); 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(); 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 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(); 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(); 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((*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 parse(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(); 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(); 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(); { 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 parse(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(); 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(); 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 parse(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 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((*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 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(); 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 parse(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(); 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 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(); 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 parse(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 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((*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 parse(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((*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 parse(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((*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 parse(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((*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 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((*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 parse(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(); 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(); 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(); 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((*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 parse(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(); 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(); 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(); 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(); 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(); 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 parse(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((*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(); 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(); 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(); 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((*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 parse(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 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((*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 parse(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(); 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(); 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(); 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(); 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 parse(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(); 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((*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 parse(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(); 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(); 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(); 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 parse(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(); 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(); 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(); 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(); 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 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((*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 parse(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 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((*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(); 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 parse(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(); 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(); 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 parse(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(); 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((*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((*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((*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((*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::DownloadProvideAuth: return "download.provideAuth"; 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_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.provideAuth") return Method::DownloadProvideAuth; 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::DownloadProvideAuth: return true; 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::DownloadProvideAuth: return t == Transport::Uds ? true : false; 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::DownloadProvideAuth: return 5000; 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_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(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()); 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(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::CaptureOffer: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::CategoryList: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::CategoryRemove: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::CategoryUpsert: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadAdd: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadAddBatch: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadCancel: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadGet: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadList: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadPause: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadProbe: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadProvideAuth: { auto p = parse(params, "params"); if (!p) return make_error(id, ErrorCode::InvalidParams, p.error().message, nlohmann::json{{"path", p.error().path}}); auto r = handler.on_download_provideAuth(*p); if (!r) return make_error(id, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadRefreshUrl: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadRemove: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadResume: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadStart: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::DownloadUpdate: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::GrabberHarvest: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::GrabberStart: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::GrabberStatus: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::LimiterGet: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::LimiterSet: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::MediaAddVariant: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::MediaListVariants: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::QueueList: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::QueueReorder: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::QueueStart: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::QueueStop: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::QueueUpsert: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::RulesList: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::RulesUpsert: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::ScheduleGet: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::ScheduleSet: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::SessionHello: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::SessionPair: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::SessionSubscribe: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::SettingsGet: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } case Method::SettingsSet: { auto p = parse(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, r.error().code, r.error().message, r.error().data); nlohmann::json out = *r; return make_result(id, std::move(out)); } } return make_error(id, ErrorCode::MethodNotFound, "no such method"); } } // namespace velox::proto