Google_Protobuf_Wrappers+Extensions.swift 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // Sources/SwiftProtobuf/Google_Protobuf_Wrappers+Extensions.swift - Well-known wrapper type extensions
  2. //
  3. // Copyright (c) 2014 - 2016 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. /// Extensions to the well-known types in wrapper.proto that customize the JSON
  12. /// format of those messages and provide convenience initializers from literals.
  13. ///
  14. // -----------------------------------------------------------------------------
  15. import Foundation
  16. /// Internal protocol that minimizes the code duplication across the multiple
  17. /// wrapper types extended below.
  18. protocol ProtobufWrapper {
  19. /// The wrapped protobuf type (for example, `ProtobufDouble`).
  20. associatedtype WrappedType: FieldType
  21. /// Exposes the generated property to the extensions here.
  22. var value: WrappedType.BaseType { get set }
  23. /// Exposes the parameterless initializer to the extensions here.
  24. init()
  25. /// Creates a new instance of the wrapper with the given value.
  26. init(_ value: WrappedType.BaseType)
  27. }
  28. extension ProtobufWrapper {
  29. mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
  30. var v: WrappedType.BaseType?
  31. try WrappedType.decodeSingular(value: &v, from: &decoder)
  32. value = v ?? WrappedType.proto3DefaultValue
  33. }
  34. }
  35. extension Google_Protobuf_DoubleValue:
  36. ProtobufWrapper, ExpressibleByFloatLiteral, _CustomJSONCodable
  37. {
  38. public typealias WrappedType = ProtobufDouble
  39. public typealias FloatLiteralType = WrappedType.BaseType
  40. public init(_ value: WrappedType.BaseType) {
  41. self.init()
  42. self.value = value
  43. }
  44. public init(floatLiteral: FloatLiteralType) {
  45. self.init(floatLiteral)
  46. }
  47. func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  48. if value.isFinite {
  49. // Swift 4.2 and later guarantees that this is accurate
  50. // enough to parse back to the exact value on the other end.
  51. return value.description
  52. } else {
  53. // Protobuf-specific handling of NaN and infinities
  54. var encoder = JSONEncoder()
  55. encoder.putDoubleValue(value: value)
  56. return encoder.stringResult
  57. }
  58. }
  59. }
  60. extension Google_Protobuf_FloatValue:
  61. ProtobufWrapper, ExpressibleByFloatLiteral, _CustomJSONCodable
  62. {
  63. public typealias WrappedType = ProtobufFloat
  64. public typealias FloatLiteralType = Float
  65. public init(_ value: WrappedType.BaseType) {
  66. self.init()
  67. self.value = value
  68. }
  69. public init(floatLiteral: FloatLiteralType) {
  70. self.init(floatLiteral)
  71. }
  72. func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  73. if value.isFinite {
  74. // Swift 4.2 and later guarantees that this is accurate
  75. // enough to parse back to the exact value on the other end.
  76. return value.description
  77. } else {
  78. // Protobuf-specific handling of NaN and infinities
  79. var encoder = JSONEncoder()
  80. encoder.putFloatValue(value: value)
  81. return encoder.stringResult
  82. }
  83. }
  84. }
  85. extension Google_Protobuf_Int64Value:
  86. ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable
  87. {
  88. public typealias WrappedType = ProtobufInt64
  89. public typealias IntegerLiteralType = WrappedType.BaseType
  90. public init(_ value: WrappedType.BaseType) {
  91. self.init()
  92. self.value = value
  93. }
  94. public init(integerLiteral: IntegerLiteralType) {
  95. self.init(integerLiteral)
  96. }
  97. func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  98. var encoded = value.description
  99. if !options.alwaysPrintInt64sAsNumbers {
  100. encoded = "\"" + encoded + "\""
  101. }
  102. return encoded
  103. }
  104. }
  105. extension Google_Protobuf_UInt64Value:
  106. ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable
  107. {
  108. public typealias WrappedType = ProtobufUInt64
  109. public typealias IntegerLiteralType = WrappedType.BaseType
  110. public init(_ value: WrappedType.BaseType) {
  111. self.init()
  112. self.value = value
  113. }
  114. public init(integerLiteral: IntegerLiteralType) {
  115. self.init(integerLiteral)
  116. }
  117. func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  118. var encoded = String(value)
  119. if !options.alwaysPrintInt64sAsNumbers {
  120. encoded = "\"" + encoded + "\""
  121. }
  122. return encoded
  123. }
  124. }
  125. extension Google_Protobuf_Int32Value:
  126. ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable
  127. {
  128. public typealias WrappedType = ProtobufInt32
  129. public typealias IntegerLiteralType = WrappedType.BaseType
  130. public init(_ value: WrappedType.BaseType) {
  131. self.init()
  132. self.value = value
  133. }
  134. public init(integerLiteral: IntegerLiteralType) {
  135. self.init(integerLiteral)
  136. }
  137. func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  138. String(value)
  139. }
  140. }
  141. extension Google_Protobuf_UInt32Value:
  142. ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable
  143. {
  144. public typealias WrappedType = ProtobufUInt32
  145. public typealias IntegerLiteralType = WrappedType.BaseType
  146. public init(_ value: WrappedType.BaseType) {
  147. self.init()
  148. self.value = value
  149. }
  150. public init(integerLiteral: IntegerLiteralType) {
  151. self.init(integerLiteral)
  152. }
  153. func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  154. String(value)
  155. }
  156. }
  157. extension Google_Protobuf_BoolValue:
  158. ProtobufWrapper, ExpressibleByBooleanLiteral, _CustomJSONCodable
  159. {
  160. public typealias WrappedType = ProtobufBool
  161. public typealias BooleanLiteralType = Bool
  162. public init(_ value: WrappedType.BaseType) {
  163. self.init()
  164. self.value = value
  165. }
  166. public init(booleanLiteral: Bool) {
  167. self.init(booleanLiteral)
  168. }
  169. func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  170. value ? "true" : "false"
  171. }
  172. }
  173. extension Google_Protobuf_StringValue:
  174. ProtobufWrapper, ExpressibleByStringLiteral, _CustomJSONCodable
  175. {
  176. public typealias WrappedType = ProtobufString
  177. public typealias StringLiteralType = String
  178. public typealias ExtendedGraphemeClusterLiteralType = String
  179. public typealias UnicodeScalarLiteralType = String
  180. public init(_ value: WrappedType.BaseType) {
  181. self.init()
  182. self.value = value
  183. }
  184. public init(stringLiteral: String) {
  185. self.init(stringLiteral)
  186. }
  187. public init(extendedGraphemeClusterLiteral: String) {
  188. self.init(extendedGraphemeClusterLiteral)
  189. }
  190. public init(unicodeScalarLiteral: String) {
  191. self.init(unicodeScalarLiteral)
  192. }
  193. func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  194. var encoder = JSONEncoder()
  195. encoder.putStringValue(value: value)
  196. return encoder.stringResult
  197. }
  198. }
  199. extension Google_Protobuf_BytesValue: ProtobufWrapper, _CustomJSONCodable {
  200. public typealias WrappedType = ProtobufBytes
  201. public init(_ value: WrappedType.BaseType) {
  202. self.init()
  203. self.value = value
  204. }
  205. func encodedJSONString(options: JSONEncodingOptions) throws -> String {
  206. var encoder = JSONEncoder()
  207. encoder.putBytesValue(value: value)
  208. return encoder.stringResult
  209. }
  210. }