Skip to content

Instantly share code, notes, and snippets.

@ryantxr
Last active August 19, 2017 22:13
Show Gist options
  • Save ryantxr/b78607eb05f031653dfe824823da4642 to your computer and use it in GitHub Desktop.
Save ryantxr/b78607eb05f031653dfe824823da4642 to your computer and use it in GitHub Desktop.
Initialize a struct from data, dictionary etc
// Credit: https://stackoverflow.com/users/887210/colgraff
struct Header {
let version : UInt
let options : UInt
let records : UInt
}
// adds marshaling
extension Header {
enum Keys: String { case version, options, records }
init?(settings: [Keys:Any]) {
guard
let version = settings[.version] as? UInt,
let marshalled = Header.marshal(version: version)(settings)
else { return nil }
self = marshalled
}
// Execute marshalling
static func marshal(version: UInt) -> ([Keys:Any]) -> Header? {
switch version {
case 0: return marshal0
default: return { (_) -> Header? in return nil } // no match, by default returns a `nil`
}
}
// Version 0 marshaling
static private var marshal0: (([Keys:Any]) -> Header?) = { (settings) -> Header? in
guard let version = settings[.version] as? UInt else { return nil }
guard let options = settings[.options] as? UInt else { return nil }
guard let records = settings[.records] as? UInt else { return nil }
return Header(version: version, options: options, records: records)
}
}
let data: [Header.Keys: UInt] = [.version: 0, .options: 5, .records: 121]
if let foo = Header(settings: data) {
print(foo) // Header(version: 5, options: 5, records: 121)
}
@colgraff
Copy link

I simplified the logic a bit by moving the version check into the marshal method. Take a look at my fork.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment