CodableProtoEnum.swift 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright 2024 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /// A type that represents a Protocol Buffer raw enum value.
  15. protocol ProtoEnum: Sendable {
  16. /// The type representing the valid values for the protobuf enum.
  17. ///
  18. /// > Important: This type must conform to `RawRepresentable` with the `RawValue == String`.
  19. ///
  20. /// This is typically a Swift enum, e.g.:
  21. /// ```
  22. /// enum Kind: String {
  23. /// case north = "WIND_DIRECTION_NORTH"
  24. /// case south = "WIND_DIRECTION_SOUTH"
  25. /// case east = "WIND_DIRECTION_EAST"
  26. /// case west = "WIND_DIRECTION_WEST"
  27. /// }
  28. /// ```
  29. associatedtype Kind: RawRepresentable<String>
  30. /// Returns the raw string value of the enum.
  31. var rawValue: String { get }
  32. /// Create a new instance of the specified type from a raw enum value.
  33. init(rawValue: String)
  34. /// Creates a new instance from the ``Kind``'s raw value.
  35. ///
  36. /// > Important: A default implementation is provided.
  37. init(kind: Kind)
  38. }
  39. /// A type that can be decoded from a Protocol Buffer raw enum value.
  40. ///
  41. /// Protobuf enums are represented as strings in JSON. A default `Decodable` implementation is
  42. /// provided when conforming to this type.
  43. protocol DecodableProtoEnum: ProtoEnum, Decodable {
  44. /// Returns the ``VertexLog/MessageCode`` associated with unrecognized (unknown) enum values.
  45. static var unrecognizedValueMessageCode: VertexLog.MessageCode { get }
  46. /// Creates a new instance by decoding from the given decoder.
  47. ///
  48. /// > Important: A default implementation is provided.
  49. init(from decoder: any Decoder) throws
  50. }
  51. /// A type that can be encoded as a Protocol Buffer enum value.
  52. ///
  53. /// Protobuf enums are represented as strings in JSON. A default `Encodable` implementation is
  54. /// provided when conforming to this type.
  55. protocol EncodableProtoEnum: ProtoEnum, Encodable {
  56. /// Encodes this value into the given encoder.
  57. ///
  58. /// > Important: A default implementation is provided.
  59. func encode(to encoder: any Encoder) throws
  60. }
  61. /// A type that can be decoded and encoded from a Protocol Buffer raw enum value.
  62. ///
  63. /// See ``ProtoEnum``, ``DecodableProtoEnum`` and ``EncodableProtoEnum`` for more details.
  64. protocol CodableProtoEnum: DecodableProtoEnum, EncodableProtoEnum {}
  65. // MARK: - Default Implementations
  66. // Default implementation of `init(kind: Kind)` for types conforming to `ProtoEnum`.
  67. extension ProtoEnum {
  68. init(kind: Kind) {
  69. self = Self(rawValue: kind.rawValue)
  70. }
  71. }
  72. // Default `Decodable` implementation for types conforming to `DecodableProtoEnum`.
  73. extension DecodableProtoEnum {
  74. // Note: Initializer 'init(from:)' must be declared public because it matches a requirement in
  75. // public protocol 'Decodable'.
  76. public init(from decoder: Decoder) throws {
  77. let rawValue = try decoder.singleValueContainer().decode(String.self)
  78. self = Self(rawValue: rawValue)
  79. if Kind(rawValue: rawValue) == nil {
  80. VertexLog.error(
  81. code: Self.unrecognizedValueMessageCode,
  82. """
  83. Unrecognized \(Self.self) with value "\(rawValue)":
  84. - Check for updates to the SDK as support for "\(rawValue)" may have been added; see \
  85. release notes at https://firebase.google.com/support/release-notes/ios
  86. - Search for "\(rawValue)" in the Firebase Apple SDK Issue Tracker at \
  87. https://github.com/firebase/firebase-ios-sdk/issues and file a Bug Report if none found
  88. """
  89. )
  90. }
  91. }
  92. }
  93. // Default `Encodable` implementation for types conforming to `EncodableProtoEnum`.
  94. extension EncodableProtoEnum {
  95. // Note: Method 'encode(to:)' must be declared public because it matches a requirement in public
  96. // protocol 'Encodable'.
  97. public func encode(to encoder: any Encoder) throws {
  98. var container = encoder.singleValueContainer()
  99. try container.encode(rawValue)
  100. }
  101. }