Google_Protobuf_Struct+Extensions.swift 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Sources/SwiftProtobuf/Google_Protobuf_Struct+Extensions.swift - Struct extensions
  2. //
  3. // Copyright (c) 2014 - 2017 Apple Inc. and the project authors
  4. // Licensed under Apache License v2.0 with Runtime Library Exception
  5. //
  6. // See LICENSE.txt for license information:
  7. // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
  8. //
  9. // -----------------------------------------------------------------------------
  10. ///
  11. /// Struct is a well-known message type that can be used to parse or encode
  12. /// arbitrary JSON objects without a predefined schema.
  13. ///
  14. // -----------------------------------------------------------------------------
  15. extension Google_Protobuf_Struct: ExpressibleByDictionaryLiteral {
  16. public typealias Key = String
  17. public typealias Value = Google_Protobuf_Value
  18. /// Creates a new `Google_Protobuf_Struct` from a dictionary of string keys to
  19. /// values of type `Google_Protobuf_Value`.
  20. public init(dictionaryLiteral: (String, Google_Protobuf_Value)...) {
  21. self.init()
  22. for (k, v) in dictionaryLiteral {
  23. fields[k] = v
  24. }
  25. }
  26. }
  27. extension Google_Protobuf_Struct: _CustomJSONCodable {
  28. internal func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  29. var jsonEncoder = JSONEncoder()
  30. jsonEncoder.startObject()
  31. var mapVisitor = JSONMapEncodingVisitor(encoder: jsonEncoder, options: options)
  32. for (k, v) in fields {
  33. try mapVisitor.visitSingularStringField(value: k, fieldNumber: 1)
  34. try mapVisitor.visitSingularMessageField(value: v, fieldNumber: 2)
  35. }
  36. mapVisitor.encoder.endObject()
  37. return mapVisitor.encoder.stringResult
  38. }
  39. internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
  40. try decoder.scanner.skipRequiredObjectStart()
  41. if decoder.scanner.skipOptionalObjectEnd() {
  42. return
  43. }
  44. while true {
  45. let key = try decoder.scanner.nextQuotedString()
  46. try decoder.scanner.skipRequiredColon()
  47. var value = Google_Protobuf_Value()
  48. try value.decodeJSON(from: &decoder)
  49. fields[key] = value
  50. if decoder.scanner.skipOptionalObjectEnd() {
  51. return
  52. }
  53. try decoder.scanner.skipRequiredComma()
  54. }
  55. }
  56. }
  57. extension Google_Protobuf_Struct {
  58. /// Creates a new `Google_Protobuf_Struct` from a dictionary of string keys to
  59. /// values of type `Google_Protobuf_Value`.
  60. ///
  61. /// - Parameter fields: The dictionary from field names to
  62. /// `Google_Protobuf_Value` messages that should be used to create the
  63. /// `Struct`.
  64. public init(fields: [String: Google_Protobuf_Value]) {
  65. self.init()
  66. self.fields = fields
  67. }
  68. /// Accesses the `Google_Protobuf_Value` with the given key for reading and
  69. /// writing.
  70. ///
  71. /// This key-based subscript returns the `Value` for the given key if the key
  72. /// is found in the `Struct`, or nil if the key is not found. If you assign
  73. /// nil as the `Value` for the given key, the `Struct` removes that key and
  74. /// its associated `Value`.
  75. public subscript(key: String) -> Google_Protobuf_Value? {
  76. get { fields[key] }
  77. set(newValue) { fields[key] = newValue }
  78. }
  79. }