// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved. import Foundation public protocol BatchRequestChildRetrievable { var requests: [Network.BatchRequest.Child] { get } } public extension Network { struct BatchRequest: Encodable, BatchRequestChildRetrievable { /// The servers currently have a limit for the number of requests a `BatchRequest` can have, when using this we should avoid /// trying to make calls that exceed this limit as they will fail public static let childRequestLimit: Int = 20 public enum CodingKeys: String, CodingKey { // Storage Server keys case requests } let requestsKey: CodingKeys? public let requests: [Child] public init(requestsKey: CodingKeys? = nil, requests: [any ErasedPreparedRequest]) { self.requestsKey = requestsKey self.requests = requests.map { Child(request: $0) } if requests.count > BatchRequest.childRequestLimit { Log.warn("[BatchRequest] Constructed request with \(requests.count) subrequests when the limit is \(BatchRequest.childRequestLimit)") } } // MARK: - Encodable public func encode(to encoder: Encoder) throws { switch requestsKey { case .requests: var container: KeyedEncodingContainer = encoder.container(keyedBy: CodingKeys.self) try container.encode(requests, forKey: .requests) case .none: var container: SingleValueEncodingContainer = encoder.singleValueContainer() try container.encode(requests) } } // MARK: - BatchRequest.Child public struct Child: Encodable { public enum Variant { case unsupported case sogs case storageServer } enum CodingKeys: String, CodingKey { case method // SOGS keys case path case headers case json case b64 case bytes // Storage Server keys case params } let request: any ErasedPreparedRequest public func encode(to encoder: Encoder) throws { try request.encodeForBatchRequest(to: encoder) } } } }