| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // Sources/SwiftProtobuf/Array+JSONAdditions.swift - JSON format primitive types
- //
- // Copyright (c) 2014 - 2017 Apple Inc. and the project authors
- // Licensed under Apache License v2.0 with Runtime Library Exception
- //
- // See LICENSE.txt for license information:
- // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
- //
- // -----------------------------------------------------------------------------
- ///
- /// Extensions to `Array` to support JSON encoding/decoding.
- ///
- // -----------------------------------------------------------------------------
- import Foundation
- /// JSON encoding and decoding methods for arrays of messages.
- extension Message {
- /// Returns a string containing the JSON serialization of the messages.
- ///
- /// Unlike binary encoding, presence of required fields is not enforced when
- /// serializing to JSON.
- ///
- /// - Returns: A string containing the JSON serialization of the messages.
- /// - Parameters:
- /// - collection: The list of messages to encode.
- /// - options: The JSONEncodingOptions to use.
- /// - Throws: ``JSONEncodingError`` if encoding fails.
- public static func jsonString<C: Collection>(
- from collection: C,
- options: JSONEncodingOptions = JSONEncodingOptions()
- ) throws -> String where C.Iterator.Element == Self {
- let data: [UInt8] = try jsonUTF8Bytes(from: collection, options: options)
- return String(bytes: data, encoding: .utf8)!
- }
- /// Returns a `SwiftProtobufContiguousBytes` containing the UTF-8 JSON serialization of the messages.
- ///
- /// Unlike binary encoding, presence of required fields is not enforced when
- /// serializing to JSON.
- ///
- /// - Returns: A `SwiftProtobufContiguousBytes` containing the JSON serialization of the messages.
- /// - Parameters:
- /// - collection: The list of messages to encode.
- /// - options: The JSONEncodingOptions to use.
- /// - Throws: ``JSONEncodingError`` if encoding fails.
- public static func jsonUTF8Bytes<C: Collection, Bytes: SwiftProtobufContiguousBytes>(
- from collection: C,
- options: JSONEncodingOptions = JSONEncodingOptions()
- ) throws -> Bytes where C.Iterator.Element == Self {
- var visitor = try JSONEncodingVisitor(type: Self.self, options: options)
- visitor.startArray()
- for message in collection {
- visitor.startArrayObject(message: message)
- try message.traverse(visitor: &visitor)
- visitor.endObject()
- }
- visitor.endArray()
- return Bytes(visitor.dataResult)
- }
- /// Creates a new array of messages by decoding the given string containing a
- /// serialized array of messages in JSON format.
- ///
- /// - Parameter jsonString: The JSON-formatted string to decode.
- /// - Parameter options: The JSONDecodingOptions to use.
- /// - Throws: ``JSONDecodingError`` if decoding fails.
- public static func array(
- fromJSONString jsonString: String,
- options: JSONDecodingOptions = JSONDecodingOptions()
- ) throws -> [Self] {
- try self.array(
- fromJSONString: jsonString,
- extensions: SimpleExtensionMap(),
- options: options
- )
- }
- /// Creates a new array of messages by decoding the given string containing a
- /// serialized array of messages in JSON format.
- ///
- /// - Parameter jsonString: The JSON-formatted string to decode.
- /// - Parameter extensions: The extension map to use with this decode
- /// - Parameter options: The JSONDecodingOptions to use.
- /// - Throws: ``JSONDecodingError`` if decoding fails.
- public static func array(
- fromJSONString jsonString: String,
- extensions: any ExtensionMap = SimpleExtensionMap(),
- options: JSONDecodingOptions = JSONDecodingOptions()
- ) throws -> [Self] {
- if jsonString.isEmpty {
- throw JSONDecodingError.truncated
- }
- if let data = jsonString.data(using: String.Encoding.utf8) {
- return try array(fromJSONUTF8Bytes: data, extensions: extensions, options: options)
- } else {
- throw JSONDecodingError.truncated
- }
- }
- /// Creates a new array of messages by decoding the given ``SwiftProtobufContiguousBytes``
- /// containing a serialized array of messages in JSON format, interpreting the data as
- /// UTF-8 encoded text.
- ///
- /// - Parameter jsonUTF8Bytes: The JSON-formatted data to decode, represented
- /// as UTF-8 encoded text.
- /// - Parameter options: The JSONDecodingOptions to use.
- /// - Throws: ``JSONDecodingError`` if decoding fails.
- public static func array<Bytes: SwiftProtobufContiguousBytes>(
- fromJSONUTF8Bytes jsonUTF8Bytes: Bytes,
- options: JSONDecodingOptions = JSONDecodingOptions()
- ) throws -> [Self] {
- try self.array(
- fromJSONUTF8Bytes: jsonUTF8Bytes,
- extensions: SimpleExtensionMap(),
- options: options
- )
- }
- /// Creates a new array of messages by decoding the given ``SwiftProtobufContiguousBytes``
- /// containing a serialized array of messages in JSON format, interpreting the data as
- /// UTF-8 encoded text.
- ///
- /// - Parameter jsonUTF8Bytes: The JSON-formatted data to decode, represented
- /// as UTF-8 encoded text.
- /// - Parameter extensions: The extension map to use with this decode
- /// - Parameter options: The JSONDecodingOptions to use.
- /// - Throws: ``JSONDecodingError`` if decoding fails.
- public static func array<Bytes: SwiftProtobufContiguousBytes>(
- fromJSONUTF8Bytes jsonUTF8Bytes: Bytes,
- extensions: any ExtensionMap = SimpleExtensionMap(),
- options: JSONDecodingOptions = JSONDecodingOptions()
- ) throws -> [Self] {
- try jsonUTF8Bytes.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
- var array = [Self]()
- if body.count > 0 {
- var decoder = JSONDecoder(
- source: body,
- options: options,
- messageType: Self.self,
- extensions: extensions
- )
- try decoder.decodeRepeatedMessageField(value: &array)
- if !decoder.scanner.complete {
- throw JSONDecodingError.trailingGarbage
- }
- }
- return array
- }
- }
- }
|