-
Notifications
You must be signed in to change notification settings - Fork 0
/
Storable.swift
71 lines (51 loc) · 1.95 KB
/
Storable.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
/*
Created by David Spooner
*/
import CoreData
/// Storable identifies types which can be transformed to and from StorageType, and serves as the generic constraint for our Attribute property wrapper.
public protocol Storable
{
associatedtype EncodingType : StorageType
/// Encode a value into its stored representation.
func storedValue() -> EncodingType
/// Decode a stored value back to its native representation.
static func decodeStoredValue(_ storedValue: EncodingType) -> Self
/// A value transformer name is required if the underlying storage type is transformable.
static var valueTransformerName : NSValueTransformerName? { get }
}
extension Storable
{
public static var valueTransformerName : NSValueTransformerName?
{ precondition(EncodingType.typeId != .transformable); return nil }
}
// All attribute types are trivially Storable, although conformance must be declared explicitly.
extension StorageType
{
public func storedValue() -> Self
{ self }
public static func decodeStoredValue(_ value: Self) -> Self
{ value }
}
extension Bool : Storable {}
extension Data : Storable {}
extension Date : Storable {}
extension Double : Storable {}
extension Float : Storable {}
extension Int : Storable {}
extension Int16 : Storable {}
extension Int32 : Storable {}
extension Int64 : Storable {}
extension String : Storable {}
extension URL : Storable {}
extension UUID : Storable {}
// A RawRepresentable is Storable when its RawValue is an attribute type, although conformance must be declared explicitly on concrete types.
extension RawRepresentable where RawValue : StorageType
{
public func storedValue() -> RawValue
{ rawValue }
public static func decodeStoredValue(_ storedValue: RawValue) -> Self
{
guard let value = Self(rawValue: storedValue) else { fatalError("'\(storedValue)' is not an acceptible raw value of \(Self.self)") }
return value
}
}