tangled
alpha
login
or
join now
khanwinter.com
/
CBOR
2
fork
atom
A fast, safe, and efficient CBOR serialization library for Swift on any platform.
swiftpackageindex.com/thecoolwinter/CBOR/1.1.1/documentation/cbor
atproto
swift
cbor
2
fork
atom
overview
issues
pulls
pipelines
Relax Requirements for Decoding Dates
Khan Winter
5 months ago
848f006e
62a85cf4
+27
-17
1 changed file
expand all
collapse all
unified
split
Sources
CBOR
Decoder
Containers
SingleValueCBORDecodingContainer.swift
+27
-17
Sources/CBOR/Decoder/Containers/SingleValueCBORDecodingContainer.swift
···
129
129
return string
130
130
}
131
131
132
132
+
// Attempt first to decode a tagged date value, then move on and try decoding any of the following as a date:
133
133
+
// - Int
134
134
+
// - Float/Double/Float16
135
135
+
// - ISO String
132
136
private func _decode(_: Date.Type) throws -> Date {
133
133
-
let argument = try checkType(.tagged, arguments: 0, 1, as: Date.self)
134
134
-
if argument == 0 {
135
135
-
// String
136
136
-
return try decodeStringDate()
137
137
-
} else {
138
138
-
return try decodeEpochDate()
137
137
+
if let argument = try? checkType(.tagged, arguments: 0, 1, as: Date.self) {
138
138
+
let taggedData = context.results.loadTagData(tagMapIndex: data.mapOffset)
139
139
+
if argument == 0 {
140
140
+
// String
141
141
+
return try decodeStringDate(data: taggedData)
142
142
+
} else {
143
143
+
return try decodeEpochDate(data: taggedData)
144
144
+
}
139
145
}
146
146
+
147
147
+
let region = context.results.load(at: data.mapOffset)
148
148
+
guard let date = (try? decodeStringDate(data: region)) ?? (try? decodeEpochDate(data: region)) else {
149
149
+
throw DecodingError.typeMismatch(Date.self, context.error("Failed to decode a valid `Date` value."))
150
150
+
}
151
151
+
return date
140
152
}
141
153
142
142
-
private func decodeStringDate() throws -> Date {
143
143
-
let taggedData = context.results.loadTagData(tagMapIndex: data.mapOffset)
144
144
-
let string = try SingleValueCBORDecodingContainer(context: context, data: taggedData).decode(String.self)
154
154
+
private func decodeStringDate(data: DataRegion) throws -> Date {
155
155
+
let string = try SingleValueCBORDecodingContainer(context: context, data: data).decode(String.self)
145
156
#if canImport(FoundationEssentials)
146
157
guard let date = try? Date.ISO8601FormatStyle().parse(string) else {
147
158
throw DecodingError.dataCorrupted(context.error("Failed to decode date from \"\(string)\""))
···
154
165
return date
155
166
}
156
167
157
157
-
private func decodeEpochDate() throws -> Date {
168
168
+
private func decodeEpochDate(data: DataRegion) throws -> Date {
158
169
// Epoch Timestamp, can be a floating point or positive/negative integer value
159
159
-
let taggedData = context.results.loadTagData(tagMapIndex: data.mapOffset)
160
160
-
switch (taggedData.type, taggedData.argument) {
170
170
+
switch (data.type, data.argument) {
161
171
case (.uint, _):
162
162
-
let int = try taggedData.readInt(as: Int.self)
172
172
+
let int = try data.readInt(as: Int.self)
163
173
return Date(timeIntervalSince1970: Double(int))
164
174
case (.nint, _):
165
165
-
let int = -1 - (try taggedData.readInt(as: Int.self))
175
175
+
let int = -1 - (try data.readInt(as: Int.self))
166
176
return Date(timeIntervalSince1970: Double(int))
167
177
case (.simple, 25), (.simple, 26):
168
178
// Float
169
169
-
let float = try SingleValueCBORDecodingContainer(context: context, data: taggedData).decode(Float.self)
179
179
+
let float = try SingleValueCBORDecodingContainer(context: context, data: data).decode(Float.self)
170
180
return Date(timeIntervalSince1970: Double(float))
171
181
case (.simple, 27):
172
182
// Double
173
173
-
let double = try SingleValueCBORDecodingContainer(context: context, data: taggedData).decode(Double.self)
183
183
+
let double = try SingleValueCBORDecodingContainer(context: context, data: data).decode(Double.self)
174
184
return Date(timeIntervalSince1970: double)
175
185
default:
176
186
throw DecodingError.typeMismatch(
177
187
Date.self,
178
178
-
context.error("Invalid type found for epoch date: \(taggedData.type) at \(taggedData.globalIndex)")
188
188
+
context.error("Invalid type found for epoch date: \(data.type) at \(data.globalIndex)")
179
189
)
180
190
}
181
191
}