forked from mattpolzin/JSONAPI
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathId.swift
More file actions
121 lines (97 loc) · 3.5 KB
/
Id.swift
File metadata and controls
121 lines (97 loc) · 3.5 KB
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//
// Id.swift
// JSONAPI
//
// Created by Mathew Polzin on 7/24/18.
//
/// All types that are RawIdType and additionally
/// Unidentified conform to this protocol. You
/// should not add conformance to this protocol
/// directly.
public protocol MaybeRawId: Codable, Equatable {}
/// Any type that you would like to be encoded to and
/// decoded from JSON API ids should conform to this
/// protocol. Conformance for `String` is given.
public protocol RawIdType: MaybeRawId, Hashable {}
/// If you would like to be able to create new
/// Entities with Ids backed by a RawIdType then
/// your Id type should conform to
/// `CreatableRawIdType`.
/// Conformances for `String` and `UUID`
/// are given in the README for this library.
public protocol CreatableRawIdType: RawIdType {
static func unique() -> Self
}
extension String: RawIdType {}
/// A type that can be used as the `MaybeRawId` for a `ResourceObject` that does not
/// have an Id (most likely because it was created by a client and the server will be responsible
/// for assigning it an Id).
public struct Unidentified: MaybeRawId, CustomStringConvertible {
public init() {}
public var description: String { return "Unidentified" }
}
public protocol OptionalId: Codable {
associatedtype IdentifiableType: JSONAPI.JSONTyped
associatedtype RawType: MaybeRawId
var rawValue: RawType { get }
init(rawValue: RawType)
}
/// marker protocol
public protocol AbstractId {}
public protocol IdType: AbstractId, OptionalId, CustomStringConvertible, Hashable where RawType: RawIdType {}
extension Optional: MaybeRawId where Wrapped: Codable & Equatable {}
extension Optional: OptionalId where Wrapped: IdType {
public typealias IdentifiableType = Wrapped.IdentifiableType
public typealias RawType = Wrapped.RawType?
public var rawValue: Wrapped.RawType? {
guard case .some(let value) = self else {
return nil
}
return value.rawValue
}
public init(rawValue: Wrapped.RawType?) {
self = rawValue.map { Wrapped(rawValue: $0) }
}
}
public extension IdType {
var description: String { return "Id(\(String(describing: rawValue)))" }
}
public protocol CreatableIdType: IdType {
init()
}
/// An ResourceObject ID. These IDs can be encoded to or decoded from
/// JSON API IDs.
public struct Id<RawType: MaybeRawId, IdentifiableType: JSONAPI.JSONTyped>: Equatable, OptionalId {
public let rawValue: RawType
public init(rawValue: RawType) {
self.rawValue = rawValue
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawValue = try container.decode(RawType.self)
self.init(rawValue: rawValue)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
}
}
extension Id: Hashable where RawType: RawIdType {
public func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(Self.self))
hasher.combine(rawValue)
}
}
extension Id: CustomStringConvertible, AbstractId, IdType where RawType: RawIdType {
public static func id(from rawValue: RawType) -> Id<RawType, IdentifiableType> {
return Id(rawValue: rawValue)
}
}
extension Id: CreatableIdType where RawType: CreatableRawIdType {
public init() {
rawValue = .unique()
}
}
extension Id where RawType == Unidentified {
public static var unidentified: Id { return .init(rawValue: Unidentified()) }
}