-
-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathLeafDataStorage.swift
More file actions
143 lines (124 loc) · 4.84 KB
/
LeafDataStorage.swift
File metadata and controls
143 lines (124 loc) · 4.84 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import Foundation
import NIOCore
import NIOFoundationCompat
indirect enum LeafDataStorage: Equatable, CustomStringConvertible, Sendable {
// MARK: - Cases
// Static values
case bool(Bool)
case string(String)
case int(Int)
case double(Double)
case data(Data)
// Collections
case dictionary([String: LeafData])
case array([LeafData])
// Wrapped `Optional<LeafDataStorage>`
case optional(_ wrapped: LeafDataStorage?, _ type: LeafData.NaturalType)
// MARK: Properties
var concreteType: LeafData.NaturalType {
switch self {
// Concrete Types
case .array: .array
case .bool: .bool
case .data: .data
case .dictionary: .dictionary
case .double: .double
case .int: .int
case .string: .string
// Optional Types
case .optional(_, let t): t
}
}
// MARK: Functions
/// Will resolve anything and unwrap optionals
func resolve() -> LeafDataStorage {
return switch self {
case .optional(let o, _): o ?? self
case .array(let a): .array(a.map { .init($0.storage.resolve()) })
case .dictionary(let d): .dictionary(d.mapValues { .init($0.storage.resolve()) })
default: self
}
}
/// Serialize anything to a string.
func serialize() -> String {
switch self {
case .bool(let b): LeafConfiguration.boolFormatter(b)
case .int(let i): LeafConfiguration.intFormatter(i)
case .double(let d): LeafConfiguration.doubleFormatter(d)
case .string(let s): LeafConfiguration.stringFormatter(s)
case .data(let d): LeafConfiguration.dataFormatter(d) ?? LeafConfiguration.nilFormatter()
case .optional(let o, _): o?.serialize() ?? LeafConfiguration.nilFormatter()
case .array(let a): LeafConfiguration.arrayFormatter(a.map { $0.storage.serialize() })
case .dictionary(let d): LeafConfiguration.dictFormatter(d.mapValues { $0.storage.serialize() })
}
}
/// Final serialization to a shared buffer
func serialize(buffer: inout ByteBuffer) throws {
switch self {
case .bool, .int, .double, .string, .optional, .array, .dictionary:
try buffer.writeString(self.serialize(), encoding: LeafConfiguration.encoding)
case .data(let d):
buffer.writeData(d)
}
}
// MARK: - Equatable Conformance
/// Strict equality comparision, with nil being equal
static func == (lhs: LeafDataStorage, rhs: LeafDataStorage) -> Bool {
switch (lhs, rhs) {
// Both optional and nil
case (.optional(nil, _), .optional(nil, _)): true
// Both optional and non-nil
case (.optional(let l?, _), .optional(let r?, _)): l == r
// One or the other optional and non-nil, unwrap and compare
case (.optional(let l?, _), let r),
(let l, .optional(let r?, _)): l == r
// Direct concrete type comparisons
case ( .array(let l), .array(let r)): l == r
case (.dictionary(let l), .dictionary(let r)): l == r
case ( .bool(let l), .bool(let r)): l == r
case ( .string(let l), .string(let r)): l == r
case ( .int(let l), .int(let r)): l == r
case ( .double(let l), .double(let r)): l == r
case ( .data(let l), .data(let r)): l == r
// Any other combo is unequal
default: false
}
}
// MARK: - CustomStringConvertible
var description: String {
switch self {
case .array(let a): "array(\(a.count))"
case .bool(let b): "bool(\(b))"
case .data(let d): "data(\(d.count))"
case .dictionary(let d): "dictionary(\(d.count))"
case .double(let d): "double(\(d))"
case .int(let i): "int(\(i))"
case .optional(let o, _): "optional(\(o.map { "\($0)" } ?? "nil")))"
case .string(let s): "string(\(s))"
}
}
var short: String {
self.serialize()
}
// MARK: - Other
var isNil: Bool {
switch self {
case .optional(.none, _): true
default: false
}
}
/// Flat mapping behavior, turns non-optional into optional. Will never re-wrap optional.
var wrap: LeafDataStorage {
switch self {
case .optional: self
default: .optional(self, self.concreteType)
}
}
/// Unwrap storage optional to Swift optional.
var unwrap: LeafDataStorage? {
switch self {
case .optional(let optional, _): optional
default: self
}
}
}