@@ -275,3 +275,60 @@ extension Measurement : _ObjectTypeBridgeable {
275
275
return Measurement ( value: source!. doubleValue, unit: u)
276
276
}
277
277
}
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