Skip to content

Commit 33a1ebe

Browse files
committed
Measurement : Codable implemented
1 parent 3c9657a commit 33a1ebe

File tree

3 files changed

+283
-46
lines changed

3 files changed

+283
-46
lines changed

Foundation/Measurement.swift

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,60 @@ extension Measurement : _ObjectTypeBridgeable {
275275
return Measurement(value: source!.doubleValue, unit: u)
276276
}
277277
}
278+
279+
extension Measurement : Codable {
280+
private enum CodingKeys : Int, CodingKey {
281+
case value
282+
case unit
283+
}
284+
285+
private enum UnitCodingKeys : Int, CodingKey {
286+
case symbol
287+
case converter
288+
}
289+
290+
private enum LinearConverterCodingKeys : Int, CodingKey {
291+
case coefficient
292+
case constant
293+
}
294+
295+
public init(from decoder: Decoder) throws {
296+
let container = try decoder.container(keyedBy: CodingKeys.self)
297+
let value = try container.decode(Double.self, forKey: .value)
298+
299+
let unitContainer = try container.nestedContainer(keyedBy: UnitCodingKeys.self, forKey: .unit)
300+
let symbol = try unitContainer.decode(String.self, forKey: .symbol)
301+
302+
let unit: UnitType
303+
if UnitType.self is Dimension.Type {
304+
let converterContainer = try unitContainer.nestedContainer(keyedBy: LinearConverterCodingKeys.self, forKey: .converter)
305+
let coefficient = try converterContainer.decode(Double.self, forKey: .coefficient)
306+
let constant = try converterContainer.decode(Double.self, forKey: .constant)
307+
let unitMetaType = (UnitType.self as! Dimension.Type)
308+
unit = (unitMetaType.init(symbol: symbol, converter: UnitConverterLinear(coefficient: coefficient, constant: constant)) as! UnitType)
309+
} else {
310+
unit = UnitType(symbol: symbol)
311+
}
312+
313+
self.init(value: value, unit: unit)
314+
}
315+
316+
public func encode(to encoder: Encoder) throws {
317+
var container = encoder.container(keyedBy: CodingKeys.self)
318+
try container.encode(self.value, forKey: .value)
319+
320+
var unitContainer = container.nestedContainer(keyedBy: UnitCodingKeys.self, forKey: .unit)
321+
try unitContainer.encode(self.unit.symbol, forKey: .symbol)
322+
323+
if UnitType.self is Dimension.Type {
324+
guard type(of: (self.unit as! Dimension).converter) is UnitConverterLinear.Type else {
325+
preconditionFailure("Cannot encode a Measurement whose UnitType has a non-linear unit converter.")
326+
}
327+
328+
let converter = (self.unit as! Dimension).converter as! UnitConverterLinear
329+
var converterContainer = unitContainer.nestedContainer(keyedBy: LinearConverterCodingKeys.self, forKey: .converter)
330+
try converterContainer.encode(converter.coefficient, forKey: .coefficient)
331+
try converterContainer.encode(converter.constant, forKey: .constant)
332+
}
333+
}
334+
}

0 commit comments

Comments
 (0)