The essence of your question is that you want to avoid writing template code for all of these enumerations when implementing Argo JSONDecodable . It looks like you also added the create method, which is not part of the signature of the JSONDecodable type:
public protocol JSONDecodable { typealias DecodedType = Self class func decode(JSONValue) -> DecodedType? }
Unfortunately this is not possible. Fast protocols are not mixes. With the exception of statements, they cannot contain any code. (I really hope this will be fixed in a future Swift update. The excellent default implementations for the protocols will be awesome.)
You can, of course, simplify your implementation in several ways:
- As suggested by Tony DiPaskale, get rid of
.unknown and use the optional ones. (Also, you would have to call it .unknown . The convention for Swift enumeration values ββis to capitalize them. Proof? Look at every enum that Apple made. I can't find a single example where they start with a lowercase letter .) - Using options, your
create now just a functional alias for init? and can be implemented very simply. - As Tony suggested, create a global generic function to handle
decode . What he did not offer, although he suggested that it was implied, was to use this to implement JSONDecodable.decode . - As a meta suggestion, use the Xcode Code Snippets function to create a snippet to do this. It must be very fast.
At the request of the appellant, there is a quick implementation from the playground. I have never used Argo. In fact, I never heard of this until I saw this question. I answered this question by simply applying what I know about Swift to the consideration of the source of Argo and reasoning. This code is copied directly from the playground. He does not use Argo, but uses a reasonable facsimile of the corresponding parts. Ultimately, this question is not about Argo. This is a system like Swift, and everything in the code below correctly answers the question and proves that it is operational:
enum JSONValue { case JSONString(String) } protocol JSONDecodable { typealias DecodedType = Self class func decode(JSONValue) -> DecodedType? } protocol RawStringInitializable { init?(rawValue: String) } enum StatusValue: String, RawStringInitializable, JSONDecodable { case Ok = "ok" case Pending = "pending" case Error = "error" static func decode(j: JSONValue) -> StatusValue? { return decodeJSON(j) } } func decodeJSON<E: RawStringInitializable>(j: JSONValue) -> E? {
This is not pseudo code. It is copied directly from the Xcode workspace.
If you create the RawStringInitializable protocol, and all its enumerations implement it, you will be gold. Since your enumerations are associated with String raw values, they implicitly implement this interface anyway. You just need to make an expression. The global function decodeJSON uses this protocol to process all your enumerations polymorphically.
source share