Google_Protobuf_Value+Extensions.swift 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // Sources/SwiftProtobuf/Google_Protobuf_Value+Extensions.swift - Value 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. /// Value is a well-known message type that can be used to parse or encode
  12. /// arbitrary JSON without a predefined schema.
  13. ///
  14. // -----------------------------------------------------------------------------
  15. extension Google_Protobuf_Value: ExpressibleByIntegerLiteral {
  16. public typealias IntegerLiteralType = Int64
  17. /// Creates a new `Google_Protobuf_Value` from an integer literal.
  18. public init(integerLiteral value: Int64) {
  19. self.init(kind: .numberValue(Double(value)))
  20. }
  21. }
  22. extension Google_Protobuf_Value: ExpressibleByFloatLiteral {
  23. public typealias FloatLiteralType = Double
  24. /// Creates a new `Google_Protobuf_Value` from a floating point literal.
  25. public init(floatLiteral value: Double) {
  26. self.init(kind: .numberValue(value))
  27. }
  28. }
  29. extension Google_Protobuf_Value: ExpressibleByBooleanLiteral {
  30. public typealias BooleanLiteralType = Bool
  31. /// Creates a new `Google_Protobuf_Value` from a boolean literal.
  32. public init(booleanLiteral value: Bool) {
  33. self.init(kind: .boolValue(value))
  34. }
  35. }
  36. extension Google_Protobuf_Value: ExpressibleByStringLiteral {
  37. public typealias StringLiteralType = String
  38. public typealias ExtendedGraphemeClusterLiteralType = String
  39. public typealias UnicodeScalarLiteralType = String
  40. /// Creates a new `Google_Protobuf_Value` from a string literal.
  41. public init(stringLiteral value: String) {
  42. self.init(kind: .stringValue(value))
  43. }
  44. /// Creates a new `Google_Protobuf_Value` from a Unicode scalar literal.
  45. public init(unicodeScalarLiteral value: String) {
  46. self.init(kind: .stringValue(value))
  47. }
  48. /// Creates a new `Google_Protobuf_Value` from a character literal.
  49. public init(extendedGraphemeClusterLiteral value: String) {
  50. self.init(kind: .stringValue(value))
  51. }
  52. }
  53. extension Google_Protobuf_Value: ExpressibleByNilLiteral {
  54. /// Creates a new `Google_Protobuf_Value` from the nil literal.
  55. public init(nilLiteral: ()) {
  56. self.init(kind: .nullValue(.nullValue))
  57. }
  58. }
  59. extension Google_Protobuf_Value: _CustomJSONCodable {
  60. internal func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  61. var jsonEncoder = JSONEncoder()
  62. try serializeJSONValue(to: &jsonEncoder, options: options)
  63. return jsonEncoder.stringResult
  64. }
  65. internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
  66. let c = try decoder.scanner.peekOneCharacter()
  67. switch c {
  68. case "n":
  69. if !decoder.scanner.skipOptionalNull() {
  70. throw JSONDecodingError.failure
  71. }
  72. kind = .nullValue(.nullValue)
  73. case "[":
  74. var l = Google_Protobuf_ListValue()
  75. try l.decodeJSON(from: &decoder)
  76. kind = .listValue(l)
  77. case "{":
  78. var s = Google_Protobuf_Struct()
  79. try s.decodeJSON(from: &decoder)
  80. kind = .structValue(s)
  81. case "t", "f":
  82. let b = try decoder.scanner.nextBool()
  83. kind = .boolValue(b)
  84. case "\"":
  85. let s = try decoder.scanner.nextQuotedString()
  86. kind = .stringValue(s)
  87. default:
  88. let d = try decoder.scanner.nextDouble()
  89. kind = .numberValue(d)
  90. }
  91. }
  92. internal static func decodedFromJSONNull() -> Google_Protobuf_Value? {
  93. Google_Protobuf_Value(kind: .nullValue(.nullValue))
  94. }
  95. }
  96. extension Google_Protobuf_Value {
  97. /// Creates a new `Google_Protobuf_Value` with the given kind.
  98. fileprivate init(kind: OneOf_Kind) {
  99. self.init()
  100. self.kind = kind
  101. }
  102. /// Creates a new `Google_Protobuf_Value` whose `kind` is `numberValue` with
  103. /// the given floating-point value.
  104. public init(numberValue: Double) {
  105. self.init(kind: .numberValue(numberValue))
  106. }
  107. /// Creates a new `Google_Protobuf_Value` whose `kind` is `stringValue` with
  108. /// the given string value.
  109. public init(stringValue: String) {
  110. self.init(kind: .stringValue(stringValue))
  111. }
  112. /// Creates a new `Google_Protobuf_Value` whose `kind` is `boolValue` with the
  113. /// given boolean value.
  114. public init(boolValue: Bool) {
  115. self.init(kind: .boolValue(boolValue))
  116. }
  117. /// Creates a new `Google_Protobuf_Value` whose `kind` is `structValue` with
  118. /// the given `Google_Protobuf_Struct` value.
  119. public init(structValue: Google_Protobuf_Struct) {
  120. self.init(kind: .structValue(structValue))
  121. }
  122. /// Creates a new `Google_Protobuf_Value` whose `kind` is `listValue` with the
  123. /// given `Google_Struct_ListValue` value.
  124. public init(listValue: Google_Protobuf_ListValue) {
  125. self.init(kind: .listValue(listValue))
  126. }
  127. /// Writes out the JSON representation of the value to the given encoder.
  128. internal func serializeJSONValue(
  129. to encoder: inout JSONEncoder,
  130. options: JSONEncodingOptions
  131. ) throws {
  132. switch kind {
  133. case .nullValue?: encoder.putNullValue()
  134. case .numberValue(let v)?:
  135. guard v.isFinite else {
  136. throw JSONEncodingError.valueNumberNotFinite
  137. }
  138. encoder.putDoubleValue(value: v)
  139. case .stringValue(let v)?: encoder.putStringValue(value: v)
  140. case .boolValue(let v)?: encoder.putNonQuotedBoolValue(value: v)
  141. case .structValue(let v)?: encoder.append(text: try v.jsonString(options: options))
  142. case .listValue(let v)?: encoder.append(text: try v.jsonString(options: options))
  143. case nil: throw JSONEncodingError.missingValue
  144. }
  145. }
  146. }