Optional.swift 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2015 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. import Realm
  19. /// A protocol describing types that can parameterize a `RealmOptional`.
  20. public protocol RealmOptionalType {
  21. }
  22. public extension RealmOptionalType {
  23. /// :nodoc:
  24. static func className() -> String {
  25. return ""
  26. }
  27. }
  28. extension Int: RealmOptionalType {}
  29. extension Int8: RealmOptionalType {}
  30. extension Int16: RealmOptionalType {}
  31. extension Int32: RealmOptionalType {}
  32. extension Int64: RealmOptionalType {}
  33. extension Float: RealmOptionalType {}
  34. extension Double: RealmOptionalType {}
  35. extension Bool: RealmOptionalType {}
  36. /**
  37. A `RealmOptional` instance represents an optional value for types that can't be
  38. directly declared as `@objc` in Swift, such as `Int`, `Float`, `Double`, and `Bool`.
  39. To change the underlying value stored by a `RealmOptional` instance, mutate the instance's `value` property.
  40. */
  41. public final class RealmOptional<Value: RealmOptionalType>: RLMOptionalBase {
  42. /// The value the optional represents.
  43. public var value: Value? {
  44. get {
  45. return RLMGetOptional(self).map(dynamicBridgeCast)
  46. }
  47. set {
  48. RLMSetOptional(self, newValue.map(dynamicBridgeCast))
  49. }
  50. }
  51. /**
  52. Creates a `RealmOptional` instance encapsulating the given default value.
  53. - parameter value: The value to store in the optional, or `nil` if not specified.
  54. */
  55. public init(_ value: Value? = nil) {
  56. super.init()
  57. self.value = value
  58. }
  59. }
  60. #if swift(>=4.1)
  61. extension RealmOptional: Codable where Value: Codable {
  62. public convenience init(from decoder: Decoder) throws {
  63. self.init()
  64. // `try decoder.singleValueContainer().decode(Value?.self)` incorrectly
  65. // rejects null values: https://bugs.swift.org/browse/SR-7404
  66. let container = try decoder.singleValueContainer()
  67. self.value = container.decodeNil() ? nil : try container.decode(Value.self)
  68. }
  69. public func encode(to encoder: Encoder) throws {
  70. try self.value.encode(to: encoder)
  71. }
  72. }
  73. #endif