{"action":"created","issue":{"url":"https://api.github.com/repos/thoughtbot/Argo/issues/401","repository_url":"https://api.github.com/repos/thoughtbot/Argo","labels_url":"https://api.github.com/repos/thoughtbot/Argo/issues/401/labels{/name}","comments_url":"https://api.github.com/repos/thoughtbot/Argo/issues/401/comments","events_url":"https://api.github.com/repos/thoughtbot/Argo/issues/401/events","html_url":"https://github.com/thoughtbot/Argo/issues/401","id":169398360,"number":401,"title":"Problem with the way we use .optional","user":{"login":"pteasima","id":1642679,"avatar_url":"https://avatars.githubusercontent.com/u/1642679?v=3","gravatar_id":"","url":"https://api.github.com/users/pteasima","html_url":"https://github.com/pteasima","followers_url":"https://api.github.com/users/pteasima/followers","following_url":"https://api.github.com/users/pteasima/following{/other_user}","gists_url":"https://api.github.com/users/pteasima/gists{/gist_id}","starred_url":"https://api.github.com/users/pteasima/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pteasima/subscriptions","organizations_url":"https://api.github.com/users/pteasima/orgs","repos_url":"https://api.github.com/users/pteasima/repos","events_url":"https://api.github.com/users/pteasima/events{/privacy}","received_events_url":"https://api.github.com/users/pteasima/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/thoughtbot/Argo/labels/question","name":"question","color":"cc317c"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":9,"created_at":"2016-08-04T15:09:20Z","updated_at":"2016-10-14T19:14:54Z","closed_at":null,"body":"Hi, I've always loved the simplicity of argo's implementation. However I dont think that we can implement the optional decode operators (`<|?`, `<||?`) just by wrapping the non-optional implementation (`<|`, `<||`) in a `.optional` call. The problem is that the behavior doesnt match the documentation. I believe that the documentation describes the desired behavior, but Im not sure if it can be easily achieved. For simplicity, I will only describe the single value case (`<|?`).\r\n\r\nThe documentation states:\r\n\r\n_This operator is used to decode an optional value from the `JSON`. If the key\r\nisn't present in the `JSON`, this will still return `.Success`. However, if\r\nthe key exists **but the object assigned to that key is unable to be decoded**\r\ninto the requested type, this will return `.Failure`._\r\n\r\nHowever, if the key is present and the mapping fails with a `.MissingKey` error, the `<|?` operator returns `.Success(nil)`. This is clearly in conflict with the documentation, and the (in my opinion) expected behaviour.\r\n\r\n### Sample JSON\r\n```\r\n{\r\n  \"child\": \"anyValue\"\r\n}\r\n```\r\n\r\n### Models\r\n\r\n```\r\nstruct Parent {\r\n  let child: Child?\r\n}\r\n\r\nextension Parent: Decodable {\r\n  static func decode(json: JSON) -> Decoded<Parent> {\r\n       return curry(self.init)\r\n       <^> json <|? \"child\"\r\n}\r\n\r\nstruct Child { }\r\nextension Child: Decodable {\r\n  static func decode(json: JSON) -> Decoded<Child> {\r\n       return .Failure(.MissingKey(\"this mapping always fails\"))\r\n}\r\n```\r\n\r\nTrying to decode a `Parent` from the example JSON would return a `Parent` with `.child` set to nil, but should instead return a `Failure(MissingKey)`.\r\n\r\nI understand that this limitation may have been done to keep the implementation simple, but the least we should do is update the documentation to describe the actual behaviour.\r\n\r\nI wonder if you guys have thought about a proper solution to this. At first thought I feel like we need to report more info in the Errors, to be able to distinguish _at which level_ the .MissingKey error happened. I have long been in favour of including the whole JSON object in the error, I wonder if this would help and if this would be enough. I still think that we wouldnt be able to use the `.optional` function as we currently do, and would need to add extra check to the `<|?` and `<||?` functions.\r\n\r\n_Argo 3.1.0_\r\n_Cocoapods_\r\n"},"comment":{"url":"https://api.github.com/repos/thoughtbot/Argo/issues/comments/253895577","html_url":"https://github.com/thoughtbot/Argo/issues/401#issuecomment-253895577","issue_url":"https://api.github.com/repos/thoughtbot/Argo/issues/401","id":253895577,"user":{"login":"smug-bot","id":11213256,"avatar_url":"https://avatars.githubusercontent.com/u/11213256?v=3","gravatar_id":"","url":"https://api.github.com/users/smug-bot","html_url":"https://github.com/smug-bot","followers_url":"https://api.github.com/users/smug-bot/followers","following_url":"https://api.github.com/users/smug-bot/following{/other_user}","gists_url":"https://api.github.com/users/smug-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/smug-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smug-bot/subscriptions","organizations_url":"https://api.github.com/users/smug-bot/orgs","repos_url":"https://api.github.com/users/smug-bot/repos","events_url":"https://api.github.com/users/smug-bot/events{/privacy}","received_events_url":"https://api.github.com/users/smug-bot/received_events","type":"User","site_admin":false},"created_at":"2016-10-14T19:14:54Z","updated_at":"2016-10-14T19:14:54Z","body":"@tonyd256 Yup, you were right—`.multiple` is giving me grief now. 😛 "}}
{"actor":{"display_login":"smug-bot"}}