@@ -286,7 +286,7 @@ public struct GeoJSON: Hashable {
286286 }
287287
288288 geometry = try GeometryObject ( dict: geometryDict)
289- properties = dict [ " properties " ] as? [ String : AnyHashable ]
289+ properties = ( dict [ " properties " ] as? [ String : Any ] ) ? . compactMapValues ( Adjuster . hashable ( _ : ) )
290290 id = dict [ " id " ] as? AnyHashable
291291 }
292292
@@ -454,7 +454,7 @@ public struct GeoJSON: Hashable {
454454 let knownRootFields = [ " type " , " features " , " bbox " , " id " , " geometry " , " geometries " , " properties " , " coordinates " ]
455455 additionalFields = dict. filter { key, _ in
456456 !knownRootFields. contains ( key)
457- } . compactMapValues { $0 as? AnyHashable }
457+ } . compactMapValues ( Adjuster . hashable ( _ : ) )
458458 }
459459
460460 public init ( geoJSONString string: String ) throws {
@@ -503,30 +503,42 @@ fileprivate extension Array where Element == GeoJSON.Degrees {
503503 }
504504}
505505
506- fileprivate extension Dictionary {
507- var prune : [ String : Any ] {
508- if let compatible = pruneWorker as? [ String : Any ] {
509- return compatible
506+ fileprivate enum Adjuster {
507+ static func prune( _ value: Any ) -> Any {
508+ if let dict = value as? [ String : Any ] {
509+ return dict. mapValues ( prune ( _: ) )
510+ } else if value is Int || value is [ Int ] || value is [ [ Int ] ] || value is Bool || value is [ Bool ] || value is [ [ Bool ] ] {
511+ return value
512+ } else if let doubles = value as? [ Double ] {
513+ return doubles. prune
514+ } else if let doubless = value as? [ [ Double ] ] {
515+ return doubless. map ( \. prune)
516+ } else if let double = value as? Double {
517+ return Decimal ( double)
518+ } else if let array = value as? [ Any ] {
519+ return array. map ( prune ( _: ) )
510520 } else {
511- preconditionFailure ( )
521+ return value
512522 }
513523 }
514524
515- private var pruneWorker : [ Key : Any ] {
516- return mapValues { value in
517- if let dict = value as? [ String : Any ] {
518- return dict. prune
519- } else if value is Int || value is [ Int ] || value is [ [ Int ] ] || value is Bool || value is [ Bool ] || value is [ [ Bool ] ] {
520- return value
521- } else if let doubles = value as? [ Double ] {
522- return doubles. prune
523- } else if let doubless = value as? [ [ Double ] ] {
524- return doubless. map { $0. prune }
525- } else if let double = value as? Double {
526- return Decimal ( double)
527- } else {
528- return value
529- }
525+ static func hashable( _ value: Any ) -> AnyHashable ? {
526+ if let dict = value as? [ String : Any ] {
527+ return dict. mapValues ( hashable ( _: ) )
528+ } else if let array = value as? [ Any ] {
529+ return array. map ( hashable ( _: ) )
530+ } else if let hashable = value as? AnyHashable {
531+ return hashable
532+ } else {
533+ assertionFailure ( " Unexpected non-hashable: \( value) -- \( type ( of: value) ) " )
534+ return nil
530535 }
531536 }
532537}
538+
539+
540+ fileprivate extension Dictionary {
541+ var prune : [ Key : Any ] {
542+ mapValues ( Adjuster . prune ( _: ) )
543+ }
544+ }
0 commit comments