forked from realm/realm-swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Optional.swift
89 lines (81 loc) · 3.26 KB
/
Optional.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2015 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////
import Realm
/// Types that can be represented in a `RealmOptional`.
public protocol RealmOptionalType {}
extension Int: RealmOptionalType {}
extension Int8: RealmOptionalType {}
extension Int16: RealmOptionalType {}
extension Int32: RealmOptionalType {}
extension Int64: RealmOptionalType {}
extension Float: RealmOptionalType {}
extension Double: RealmOptionalType {}
extension Bool: RealmOptionalType {}
// Not all RealmOptionalType's can be cast to AnyObject, so handle casting logic here.
private func realmOptionalToAnyObject<T: RealmOptionalType>(value: T?) -> AnyObject? {
if let anyObjectValue: AnyObject = value as? AnyObject {
return anyObjectValue
} else if let int8Value = value as? Int8 {
return NSNumber(long: Int(int8Value))
} else if let int16Value = value as? Int16 {
return NSNumber(long: Int(int16Value))
} else if let int32Value = value as? Int32 {
return NSNumber(long: Int(int32Value))
} else if let int64Value = value as? Int64 {
return NSNumber(longLong: int64Value)
}
return nil
}
// Not all RealmOptionalType's can be cast from AnyObject, so handle casting logic here.
private func anyObjectToRealmOptional<T: RealmOptionalType>(anyObject: AnyObject?) -> T? {
if T.self is Int8.Type {
return ((anyObject as! NSNumber?)?.longValue).map { Int8($0) } as! T?
} else if T.self is Int16.Type {
return ((anyObject as! NSNumber?)?.longValue).map { Int16($0) } as! T?
} else if T.self is Int32.Type {
return ((anyObject as! NSNumber?)?.longValue).map { Int32($0) } as! T?
} else if T.self is Int64.Type {
return (anyObject as! NSNumber?)?.longLongValue as! T?
}
return anyObject as! T?
}
/**
A `RealmOptional` represents a optional value for types that can't be directly
declared as `dynamic` in Swift, such as `Int`s, `Float`, `Double`, and `Bool`.
It encapsulates a value in its `value` property, which is the only way to mutate
a `RealmOptional` property on an `Object`.
*/
public final class RealmOptional<T: RealmOptionalType>: RLMOptionalBase {
/// The value this optional represents.
public var value: T? {
get {
return anyObjectToRealmOptional(underlyingValue)
}
set {
underlyingValue = realmOptionalToAnyObject(newValue)
}
}
/**
Creates a `RealmOptional` with the given default value (defaults to `nil`).
- parameter value: The default value for this optional.
*/
public init(_ value: T? = nil) {
super.init()
self.value = value
}
}