// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. import Foundation import SessionUtilitiesKit internal extension SnodeAPI { struct BatchRequest: Encodable { let requests: [Child] init(requests: [Info]) { self.requests = requests.map { $0.child } } // MARK: - BatchRequest.Info struct Info { public let responseType: Codable.Type fileprivate let child: Child public init(request: SnodeRequest, responseType: R.Type) { self.child = Child(request: request) self.responseType = HTTP.BatchSubResponse.self } public init(request: SnodeRequest) { self.init( request: request, responseType: NoResponse.self ) } } // MARK: - BatchRequest.Child struct Child: Encodable { enum CodingKeys: String, CodingKey { case method case params } let endpoint: SnodeAPI.Endpoint /// The `jsonBodyEncoder` is used to avoid having to make `BatchSubRequest` a generic type (haven't found /// a good way to keep `BatchSubRequest` encodable using protocols unfortunately so need this work around) private let jsonBodyEncoder: ((inout KeyedEncodingContainer, CodingKeys) throws -> ())? init(request: SnodeRequest) { self.endpoint = request.endpoint self.jsonBodyEncoder = { [body = request.body] container, key in try container.encode(body, forKey: key) } } public func encode(to encoder: Encoder) throws { var container: KeyedEncodingContainer = encoder.container(keyedBy: CodingKeys.self) try container.encode(endpoint.rawValue, forKey: .method) try jsonBodyEncoder?(&container, .params) } } } }