// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. import Foundation func queryString(from queryParameters: [QueryParameter]) -> String { return queryParameters .sorted { qp1, qp2 in if qp1.key == qp2.key { return qp1.index < qp2.index } // Lexicographically sort components. for (c1, c2) in zip(qp1.key, qp2.key) { if c1 < c2 { return true } else if c1 > c2 { return false } } return true }.compactMap { queryParam in guard let encodedName = percentEncode(string: queryParameterName(from: queryParam.key)), let encodedValue = percentEncode(string: queryParam.serialized) else { return nil } return "\(encodedName)=\(encodedValue)" }.joined(separator: "&") } // Helps build nested and exploded query parameters. class QueryParameterBuilder { private var queryParameters: [QueryParameter] = [] func addQueryParameters(from serializable: Serializable?, named name: String, format: SerializableFormat, parameterDefaults: ParameterDefaults?) throws { guard let serializable = serializable ?? parameterDefaults?.defaultQueryParameter(for: name) else { return } if format.explode { queryParameters.append( contentsOf: try serializable .serializeQueryParameters(with: format) .mapKeys { parameterKey(from: $0, nameOverride: name, with: format) } ) } else { queryParameters.append(QueryParameter(key: [name], serialized: try serializable.serialize(with: format))) } } func addJSONQueryParameter(named name: String, with encodable: Encodable?) throws { guard let encodable, let encoded = try serializeEncodable(encodable) else { return } queryParameters.append(QueryParameter(key: [name], serialized: encoded)) } func build() -> [QueryParameter] { return queryParameters } } extension Array where Element == QueryParameter { func mapKeys(_ f: ([String]) -> [String]) -> [QueryParameter] { return map { QueryParameter(key: f($0.key), serialized: $0.serialized, index: $0.index) } } } private func parameterKey(from key: [String], nameOverride: String, with format: SerializableFormat) -> [String] { if format.isDeep { return [nameOverride] + key } else { return key.isEmpty ? [nameOverride] : key } } private let allowedPercentEncodingCharacters = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "-.")) private func percentEncode(string: String) -> String? { return string.addingPercentEncoding(withAllowedCharacters: allowedPercentEncodingCharacters) } private func queryParameterName(from key: [String]) -> String { guard let first = key.first else { return "" } let rest = key.dropFirst() return "\(first)\(rest.map { "[\($0)]" }.joined())" }