<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns:mv="http://macVmlSchemaUri" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Title" content="">
<meta name="Keywords" content="">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
        {font-family:"Courier New";
        panose-1:2 7 3 9 2 2 5 2 4 4;}
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:0 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Monaco;
        panose-1:2 0 5 0 0 0 0 0 0 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p
        {mso-style-priority:99;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:12.0pt;
        font-family:"Times New Roman";}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:Calibri;
        color:windowtext;}
span.msoIns
        {mso-style-type:export-only;
        mso-style-name:"";
        text-decoration:underline;
        color:teal;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1837724020;
        mso-list-template-ids:1649952886;}
@list l0:level1
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:1.0in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:"Courier New";
        mso-bidi-font-family:"Times New Roman";}
@list l0:level3
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:1.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Wingdings;}
@list l0:level4
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:2.0in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Wingdings;}
@list l0:level5
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:2.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Wingdings;}
@list l0:level6
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:3.0in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Wingdings;}
@list l0:level7
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:3.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Wingdings;}
@list l0:level8
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:4.0in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Wingdings;}
@list l0:level9
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:4.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Wingdings;}
ol
        {margin-bottom:0in;}
ul
        {margin-bottom:0in;}
--></style>
</head>
<body bgcolor="white" lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri">Hi Youming,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri">No worries. Some of the verbage overlaps enough that it makes the conversation a little difficult to follow.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri">The jist is basically that if I type my struct with an Int inside, the JSON payload contains a string, I want an Int back if at all possible. If my struct has a string, the JSON payload
has an int, I want the string. I want the struct the type specifies to at least be attempted to be given back before failing.
<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri">That’s not to say I’m only talking about doing this with Strings and Ints, just using it as an example for the conversation.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri">Hopefully that helps.
<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri">Brandon Sneed<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:Calibri"><o:p> </o:p></span></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-family:Calibri;color:black">From: </span>
</b><span style="font-family:Calibri;color:black">Youming Lin <ylin@us.ibm.com><br>
<b>Date: </b>Wednesday, August 30, 2017 at 3:19 PM<br>
<b>To: </b>"Sneed, Brandon" <brsneed@ebay.com><br>
<b>Cc: </b>Tony Parker <anthony.parker@apple.com>, "swift-corelibs-dev@swift.org" <swift-corelibs-dev@swift.org>, "swift-corelibs-dev-bounces@swift.org" <swift-corelibs-dev-bounces@swift.org><br>
<b>Subject: </b>Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p><span style="font-size:10.0pt">Brandon</span><br>
<br>
<span style="font-size:10.0pt">Sorry, I didn't realize you want it on the String type since you used other string ivars in your example as well.<br>
<br>
I'm not sure that forcing all numbers to be valid decoded strings is a good idea, because this behavior gets applied to other string ivars that you may not want to be compatible with numbers, which is the inverse of the problem you stated.<br>
<br>
A custom Codable type to represent number-equivalent strings is a better solution I think.<br>
</span><br>
<span style="font-size:10.0pt">Thanks,<br>
<br>
Youming Lin<br>
IBM Cloud, Swift@IBM, Kitura developer<br>
Austin, TX<br>
GitHub: @youming-lin</span><br>
<br>
<img width="16" height="16" id="_x0000_i1025" src="cid:image001.gif@01D321A3.E2272B40" alt="nactive hide details for "Sneed, Brandon" ---08/30/2017 04:42:39 PM---Tha"><span style="font-size:10.0pt;color:#424282">"Sneed, Brandon" ---08/30/2017 04:42:39 PM---Thanks
Youming, That’s not quite what I meant. I may have misinterpreted what Tony was saying thoug</span><br>
<br>
<span style="font-size:10.0pt;color:#5F5F5F">From: </span><span style="font-size:10.0pt">"Sneed, Brandon" <brsneed@ebay.com></span><br>
<span style="font-size:10.0pt;color:#5F5F5F">To: </span><span style="font-size:10.0pt">Youming Lin <ylin@us.ibm.com></span><br>
<span style="font-size:10.0pt;color:#5F5F5F">Cc: </span><span style="font-size:10.0pt">Tony Parker <anthony.parker@apple.com>, "swift-corelibs-dev@swift.org" <swift-corelibs-dev@swift.org>, "swift-corelibs-dev-bounces@swift.org" <swift-corelibs-dev-bounces@swift.org></span><br>
<span style="font-size:10.0pt;color:#5F5F5F">Date: </span><span style="font-size:10.0pt">08/30/2017 04:42 PM</span><br>
<span style="font-size:10.0pt;color:#5F5F5F">Subject: </span><span style="font-size:10.0pt">Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode</span><o:p></o:p></p>
<div class="MsoNormal">
<hr size="2" width="100%" noshade="" style="color:#8091A5" align="left">
</div>
<p class="MsoNormal"><br>
<br>
<br>
Thanks Youming,<br>
<br>
That’s not quite what I meant. I may have misinterpreted what Tony was saying though.<br>
<br>
I wanted to do conversion on String, not the containing type. The problem of doing it on the containing type is that as soon as you need one field to be custom, you’re roped into handling all the others. For a small struct, not a big deal, for larger ones,
it is. Something like this is what I tried:<br>
<br>
import Cocoa<br>
<br>
let jsonString = "{" +<br>
"\"name\": \"Endeavor\"," +<br>
"\"abv\": 8.9," +<br>
"\"brewery\": \"Saint Arnold\"," +<br>
"\"style\": \"ipa\"}"<br>
<br>
struct Beer: Codable {<br>
let name: String<br>
let abv: String<br>
let brewery: String<br>
let style: String<br>
}<br>
<br>
extension String {<br>
init(from decoder: Decoder) throws {<br>
print("i got hit.")<br>
let value = try decoder.singleValueContainer().decode(String.self)<br>
self.init(value)<br>
}<br>
}<br>
<br>
let jsonData = jsonString.data(using: .utf8)<br>
let decoder = JSONDecoder()<br>
let beer = try! decoder.decode(Beer.self, from: jsonData!)<br>
<br>
<b>fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [__lldb_expr_17.Beer.(CodingKeys in _C8902E33F84CE6946081129DAF1824E1).abv], debugDescription: "Expected to
decode String but found a number instead.", underlyingError: nil)): file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.59/src/swift/stdlib/public/core/ErrorType.swift, line 181</b><br>
<br>
<br>
<br>
<b>From: </b>Youming Lin <ylin@us.ibm.com><b><br>
Date: </b>Wednesday, August 30, 2017 at 2:35 PM<b><br>
To: </b>"Sneed, Brandon" <brsneed@ebay.com><b><br>
Cc: </b>Tony Parker <anthony.parker@apple.com>, "swift-corelibs-dev@swift.org" <swift-corelibs-dev@swift.org>, "swift-corelibs-dev-bounces@swift.org" <swift-corelibs-dev-bounces@swift.org><b><br>
Subject: </b>Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode<o:p></o:p></p>
<p><span style="font-size:10.0pt">Brandon<br>
<br>
I cooked up a simple example and it works as expected.<br>
</span><span style="font-family:Monaco"><br>
ylin@youming-mbpr:~/Swift/Configuration$ swift<br>
Welcome to Apple Swift version 4.0-dev (LLVM 2dedb62a0b, Clang b9d76a314c, Swift 0899bd328a). Type :help for assistance.<br>
1> import Foundation<br>
2> struct A: Codable { <br>
3. var integer: Int <br>
4. <br>
5. public init(integer: Int) { <br>
6. self.integer = integer <br>
7. } <br>
8. <br>
9. public init(from decoder: Decoder) throws { <br>
10. print("Custom decoder") <br>
11. let container = try decoder.container(keyedBy: CodingKeys.self) <br>
12. integer = try container.decode(Int.self, forKey: .integer) <br>
13. } <br>
14. } <br>
15. <br>
16. try! JSONDecoder().decode(A.self, from: JSONEncoder().encode(A(integer: 42)))<br>
Custom decoder<br>
$R0: A = {<br>
integer = 42<br>
}</span><br>
<span style="font-size:10.0pt"><br>
You should be able to implement your custom init to convert the number into a string and JSONDecoder should use that automatically.</span><br>
<span style="font-size:10.0pt"><br>
Thanks,<br>
<br>
Youming Lin<br>
IBM Cloud, Swift@IBM, Kitura developer<br>
Austin, TX<br>
GitHub: @youming-lin</span><br>
<br>
<img width="16" height="16" id="_x0000_i1027" src="cid:image002.gif@01D321A3.E2272B40" alt="active hide details for "Sneed, Brandon" ---08/30/2017 04:14:57 PM---Tha"><span style="font-size:10.0pt;color:#424282">"Sneed, Brandon" ---08/30/2017 04:14:57 PM---Thanks
Youming, Ok, thanks! I did try that, but I can’t seem to figure out how to make it actually</span><br>
<span style="font-size:10.0pt;color:#5F5F5F"><br>
From: </span><span style="font-size:10.0pt">"Sneed, Brandon" <brsneed@ebay.com><span style="color:#5F5F5F"><br>
To: </span>Youming Lin <ylin@us.ibm.com><span style="color:#5F5F5F"><br>
Cc: </span>Tony Parker <anthony.parker@apple.com>, "swift-corelibs-dev@swift.org" <swift-corelibs-dev@swift.org>, "swift-corelibs-dev-bounces@swift.org" <swift-corelibs-dev-bounces@swift.org><span style="color:#5F5F5F"><br>
Date: </span>08/30/2017 04:14 PM<span style="color:#5F5F5F"><br>
Subject: </span>Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode</span><o:p></o:p></p>
<div class="MsoNormal">
<hr size="2" width="100%" noshade="" style="color:#AAAAAA" align="left">
</div>
<p class="MsoNormal"><br>
<br>
<br>
<br>
Thanks Youming,<br>
<br>
Ok, thanks! I did try that, but I can’t seem to figure out how to make it actually get used in the decoding process. That being my preferred way, I tried it first. I chalked it not working up to Swift not knowing which of the 2 init(from decoder:) functions
to call, mine or theirs. But, maybe there’s something I’m missing here.<br>
<br>
Any insight is appreciated.<br>
<br>
Thanks!<br>
<br>
<br>
<br>
Brandon Sneed<br>
<b><br>
From: </b>Youming Lin <ylin@us.ibm.com><b><br>
Date: </b>Wednesday, August 30, 2017 at 1:18 PM<b><br>
To: </b>"Sneed, Brandon" <brsneed@ebay.com><b><br>
Cc: </b>Tony Parker <anthony.parker@apple.com>, "swift-corelibs-dev@swift.org" <swift-corelibs-dev@swift.org>, "swift-corelibs-dev-bounces@swift.org" <swift-corelibs-dev-bounces@swift.org><b><br>
Subject: </b>Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode
<o:p></o:p></p>
<p><span style="font-size:10.0pt">Brandon<br>
<br>
></span>JSON’s types effectively end up matching specifically to primitives, of which there is no mechanism to override the behavior of how a String gets decoded for instance.<span style="font-size:10.0pt"><br>
<br>
You can override the default behavior with your own custom init(from:) implementation for your Codable struct:
</span><a href="https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.proofpoint.com%2Fv2%2Furl%3Fu%3Dhttps-3A__na01.safelinks.protection.outlook.com_-3Furl-3Dhttps-253A-252F-252Fdeveloper.apple.com-252Fdocumentation-252Fswift-252Fdecodable-252F2894081-2Dinit-26data-3D02-257C01-257Cbrsneed-2540ebay.com-257C6290a819253b47b0eb2408d4efe454ae-257C46326bff992841a0baca17c16c94ea99-257C0-257C0-257C636397211330551372-26sdata-3DoLr1Q10-252BztzwG-252BCXpMinBzJNTwSy-252FjoBsKm9Glg1-252FxY-253D-26reserved-3D0%26d%3DDwMGaQ%26c%3Djf_iaSHvJObTbx-siA1ZOg%26r%3DgkRZBtsmKeGPCOlAIRJoOA%26m%3Dc3lYikOfd2-4q_nd_qMnJ4gXKIuKuxxoJRxIrIZc3Hw%26s%3Dh1azblXptqRwHqDQhejN9sSFa8dR-Gd8OkB7_6VwgNg%26e%3D&data=02%7C01%7Cbrsneed%40ebay.com%7Cebd9669255614ce4dccc08d4efef218c%7C46326bff992841a0baca17c16c94ea99%7C0%7C0%7C636397257717072726&sdata=TIZrCfocLCJGcfOj%2B9V2FEiXPSTKN4hnL1Rm03GqHvk%3D&reserved=0"><span style="font-size:10.0pt">https://developer.apple.com/documentation/swift/decodable/2894081-init</span></a><span style="font-size:10.0pt"><br>
<br>
You can check Foundation source code (i.e., the URL struct) on how this can be implemented.<br>
<br>
Thanks,<br>
<br>
Youming Lin<br>
IBM Cloud, Swift@IBM, Kitura developer<br>
Austin, TX<br>
GitHub: @youming-lin</span><br>
<br>
<img border="0" width="16" height="16" id="_x0000_i1029" src="cid:image003.gif@01D321A3.E2272B40" alt="ctive hide details for "Sneed, Brandon via swift-corelibs-dev" ---08/30"><span style="font-size:10.0pt;color:#424282">"Sneed, Brandon via swift-corelibs-dev"
---08/30/2017 03:07:05 PM---Hi Tony, I like the idea that the type itself is responsible for the conversion. My own json encode</span><span style="font-size:10.0pt;color:#5F5F5F"><br>
<br>
From: </span><span style="font-size:10.0pt">"Sneed, Brandon via swift-corelibs-dev" <swift-corelibs-dev@swift.org><span style="color:#5F5F5F"><br>
To: </span>Tony Parker <anthony.parker@apple.com><span style="color:#5F5F5F"><br>
Cc: </span>"swift-corelibs-dev@swift.org" <swift-corelibs-dev@swift.org><span style="color:#5F5F5F"><br>
Date: </span>08/30/2017 03:07 PM<span style="color:#5F5F5F"><br>
Subject: </span>Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode<span style="color:#5F5F5F"><br>
Sent by: </span>swift-corelibs-dev-bounces@swift.org</span><o:p></o:p></p>
<div class="MsoNormal">
<hr size="2" width="100%" noshade="" style="color:#AAAAAA" align="left">
</div>
<p class="MsoNormal"><br>
<br>
<br>
<br>
<br>
Hi Tony,<br>
<br>
I like the idea that the type itself is responsible for the conversion. My own json encode/decode library worked this way and it was really great, however in trying to leverage Swift4 into it, or to replace it, I just don’t see how that’s possible given how
it’s currently structured.<br>
<br>
JSON’s types effectively end up matching specifically to primitives, of which there is no mechanism to override the behavior of how a String gets decoded for instance. The only way I can think of to accomplish that is to create *<b>another</b>* type, JSONString
for example, but since String is a struct, I can’t subclass it, and instead need to have the real value buried inside of it … it seems to start getting messy very quickly. It also adds the obfuscation of dealing with yet another type, which I’m not against,
but just feels less than ideal.<br>
<br>
<br>
Brandon Sneed<b><br>
<br>
From: </b><anthony.parker@apple.com> on behalf of Tony Parker <anthony.parker@apple.com><b><br>
Date: </b>Wednesday, August 30, 2017 at 11:30 AM<b><br>
To: </b>"Sneed, Brandon" <brsneed@ebay.com><b><br>
Cc: </b>Itai Ferber <iferber@apple.com>, "swift-corelibs-dev@swift.org" <swift-corelibs-dev@swift.org><b><br>
Subject: </b>Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode<br>
<br>
I’m still not convinced that we should actually provide such a strategy. <br>
<br>
Conversions like those below seem like the domain of each type that is being decoded. If, in a particular type, the “number” can be either a true number or a string, then that type can try decoding it as one or the other and fall back as required. That puts
the responsibility of doing that kind of conversion in the type itself.<br>
<br>
JSON has very few types already. I’m not sure we want to blur the line between numbers and strings automatically…<br>
<br>
- Tony <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:4.0in">On Aug 30, 2017, at 11:24 AM, Sneed, Brandon via swift-corelibs-dev <<a href="mailto:swift-corelibs-dev@swift.org">swift-corelibs-dev@swift.org</a>> wrote:<br>
<br>
Hi Itai,<br>
<br>
No problem! Thanks for the heads up. Is there any way I could be involved? Happy to do the work to whatever guidance your team might have. I’m mostly just interested in it being there soon, hence volunteering.
<br>
<br>
Thanks!<br>
<br>
<br>
Brandon Sneed<b><br>
<br>
From: </b><<a href="mailto:iferber@apple.com">iferber@apple.com</a>> on behalf of Itai Ferber <<a href="mailto:iferber@apple.com">iferber@apple.com</a>><b><br>
Date: </b>Wednesday, August 30, 2017 at 11:22 AM<b><br>
To: </b>"Sneed, Brandon" <<a href="mailto:brsneed@ebay.com">brsneed@ebay.com</a>><b><br>
Cc: </b>"<a href="mailto:swift-corelibs-dev@swift.org">swift-corelibs-dev@swift.org</a>" <<a href="mailto:swift-corelibs-dev@swift.org">swift-corelibs-dev@swift.org</a>><b><br>
Subject: </b>Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode<span style="font-family:Helvetica"><br>
<br>
Hi Brandon,<br>
Thanks for looking at this! We’ve got plans internally to potentially add a strategy to
</span><span style="font-size:10.0pt;font-family:"Courier New"">JSONEncoder</span><span style="font-family:Helvetica">/</span><span style="font-size:10.0pt;font-family:"Courier New"">JSONDecoder</span><span style="font-family:Helvetica"> to allow lenient conversions
like this — i.e. implicitly stringify numbers (or parse them from string input), among some others.<br>
This would be opt-in for consumers of </span><span style="font-size:10.0pt;font-family:"Courier New"">JSONDecoder</span><span style="font-family:Helvetica"> while not requiring any special annotations on
</span><span style="font-size:10.0pt;font-family:"Courier New"">Codable</span><span style="font-family:Helvetica"> types.<br>
— Itai<br>
On 30 Aug 2017, at 10:59, Sneed, Brandon via swift-corelibs-dev wrote:</span><span style="color:#777777"><br>
Hi everyone,<br>
<br>
Just throwing this out to see if anyone else is working on this, or has opinions/suggestions on how it’s implemented. I’d like to add this to the Codable/JSONDecoder/JSONEncoder system if no one else is working on it.<br>
<br>
Type type conversion, I mean given this JSON payload:<br>
<br>
{<br>
"name": "Endeavor”,<br>
"abv": 8.9,<br>
"brewery": "Saint Arnold”,<br>
"style": "ipa"<br>
}<br>
<br>
and a struct defined as:<br>
<br>
struct Beer: Codable {<br>
let name: String<br>
let abv: String<br>
let brewery: String<br>
let style: BeerStyle<br>
}<br>
<br>
Notice that “abv” is a number in the JSON, but a String in the struct. I’d like to make it such that I can let the system know it’s ok to convert it from a number to a string as opposed to throwing an exception. The benefits are:<br>
<br>
1. It’s defensive; service types can change without causing my application to crash.<br>
2. It allows a developer to work with the types they want to work with as opposed to what the server provides, thus saving them time of writing a custom encode/decode code for all members.<br>
<br>
The argument against it that I’ve heard is generally “it’s a service bug, make them fix it”, which is valid but the reality is we’re not all in control of the services we injest. The same type of logic could be applied to a member name changing, though I haven’t
seen this happen often in practice. I do see types in a json payload change with some frequency though. I think much of the reason stems from the fact that type conversion in javascript is effectively free, ie: you ask for a String, you get a String if possible.<br>
<br>
To implement this type conversion in practice, looking at it from the point of view using Codable/JSON(en/de)coder, one way would be to make it opt-in:<br>
<br>
struct Beer: Codable, CodingConvertible {<br>
let name: String<br>
let abv: String<br>
let brewery: String<br>
let style: BeerStyle<br>
}<br>
<br>
I like this because looking at the struct, the members still remain clear and relatively unambiguous. The downside is it’s unknown which member is likely to get converted. And since it’s opt-in, conversion doesn’t happen if the CodingConvertible conformance
isn’t adhered to.<br>
<br>
Another option would be to box each type, like so:<br>
<br>
struct Beer: Codable {<br>
let name: String<br>
let abv: Convertible<String><br>
let brewery: String<br>
let style: BeerStyle<br>
}<br>
<br>
This seems tedious for developers, but would show which types are being converted. It does however seriously weaken benefit #1 above.<br>
<br>
Those example usages above aside, I do think it’d be best if this conversion behavior was the default and no end-developer changes required. I think that could be done without impact to code that’s been already been written against the JSON en/decode bits.<br>
<br>
I’m very open to alternatives, other ideas, or anything else you might have to say on the subject. Thanks for reading!</span><br>
<br>
<span style="color:#777777"><br>
<br>
Brandon Sneed</span><br>
<br>
<br>
<span style="font-family:Helvetica;color:#777777"><br>
<br>
_______________________________________________<br>
swift-corelibs-dev mailing list</span><u><span style="color:blue"><br>
</span></u><a href="mailto:swift-corelibs-dev@swift.org"><span style="font-family:Helvetica">swift-corelibs-dev@swift.org</span></a><u><span style="color:blue"><br>
</span></u><a href="https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.proofpoint.com%2Fv2%2Furl%3Fu%3Dhttps-3A__na01.safelinks.protection.outlook.com_-3Furl-3Dhttps-253A-252F-252Flists.swift.org-252Fmailman-252Flistinfo-252Fswift-2Dcorelibs-2Ddev-26data-3D02-257C01-257Cbrsneed-2540ebay.com-257C0e58a975be44418826d608d4efd427dc-257C46326bff992841a0baca17c16c94ea99-257C0-257C0-257C636397141865218008-26sdata-3DytYIqDtMesw4NnpUbFmiWF2-252FKfxlawG4YuVWPJd099Y-253D-26reserved-3D0%26d%3DDwMGaQ%26c%3Djf_iaSHvJObTbx-siA1ZOg%26r%3DgkRZBtsmKeGPCOlAIRJoOA%26m%3DViDSVPImta3StTVAcktby2PMF_-du5itzz47jo-tNHg%26s%3DrVZl8iT3jj1nzuDTCqZ1pkhQIZD3-Byi8PUj50swTUg%26e%3D&data=02%7C01%7Cbrsneed%40ebay.com%7C6290a819253b47b0eb2408d4efe454ae%7C46326bff992841a0baca17c16c94ea99%7C0%7C0%7C636397211330551372&sdata=GkxX7xyhtHr1zqISNmjeBhvOkVoZdOihXcaugXSK9tA%3D&reserved=0"><span style="font-family:Helvetica;color:#777777">https://lists.swift.org/mailman/listinfo/swift-corelibs-dev</span></a><span style="font-size:10.0pt;font-family:Helvetica"><br>
_______________________________________________<br>
swift-corelibs-dev mailing list</span><u><span style="color:blue"><br>
</span></u><a href="mailto:swift-corelibs-dev@swift.org"><span style="font-size:10.0pt;font-family:Helvetica">swift-corelibs-dev@swift.org</span></a><u><span style="color:blue"><br>
</span></u><a href="https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.proofpoint.com%2Fv2%2Furl%3Fu%3Dhttps-3A__na01.safelinks.protection.outlook.com_-3Furl-3Dhttps-253A-252F-252Flists.swift.org-252Fmailman-252Flistinfo-252Fswift-2Dcorelibs-2Ddev-26data-3D02-257C01-257Cbrsneed-2540ebay.com-257Cf2eba37a5b40474e09b108d4efd5372d-257C46326bff992841a0baca17c16c94ea99-257C0-257C0-257C636397146413883032-26sdata-3DC1-252F8MXq-252Fh7NHgyxeKDkcHDcigtQjSztCaAeUxBzYZ3g-253D-26reserved-3D0%26d%3DDwMGaQ%26c%3Djf_iaSHvJObTbx-siA1ZOg%26r%3DgkRZBtsmKeGPCOlAIRJoOA%26m%3DViDSVPImta3StTVAcktby2PMF_-du5itzz47jo-tNHg%26s%3DLQ0cgWtC9rXRTDLu0W58VIukWrsRssHsIMGb9U6Y0MU%26e%3D&data=02%7C01%7Cbrsneed%40ebay.com%7C6290a819253b47b0eb2408d4efe454ae%7C46326bff992841a0baca17c16c94ea99%7C0%7C0%7C636397211330551372&sdata=afQLw7%2FVip%2Bts1P60ALOHrTNap93519tWLjYzkS2o5Q%3D&reserved=0"><span style="font-size:10.0pt;font-family:Helvetica">https://lists.swift.org/mailman/listinfo/swift-corelibs-dev</span></a><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Courier New"">_______________________________________________<br>
swift-corelibs-dev mailing list<br>
swift-corelibs-dev@swift.org</span><u><span style="color:blue"><br>
</span></u><a href="https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.proofpoint.com%2Fv2%2Furl%3Fu%3Dhttps-3A__na01.safelinks.protection.outlook.com_-3Furl-3Dhttps-253A-252F-252Furldefense.proofpoint.com-252Fv2-252Furl-253Fu-253Dhttps-2D3A-5F-5Flists.swift.org-5Fmailman-5Flistinfo-5Fswift-2D2Dcorelibs-2D2Ddev-2526d-253DDwIGaQ-2526c-253Djf-5FiaSHvJObTbx-2DsiA1ZOg-2526r-253DgkRZBtsmKeGPCOlAIRJoOA-2526m-253DViDSVPImta3StTVAcktby2PMF-5F-2Ddu5itzz47jo-2DtNHg-2526s-253DzRuNQ3NLxpfhFBewRTkoMWZnpvHlm6Ja-2Dot9-5FpwAgqI-2526e-253D-26data-3D02-257C01-257Cbrsneed-2540ebay.com-257C6290a819253b47b0eb2408d4efe454ae-257C46326bff992841a0baca17c16c94ea99-257C0-257C0-257C636397211330551372-26sdata-3DkUgv-252B3QRVpUH5JGBclTqYHheS-252FfaDPIWTrTk-252F-252BX8J-252Bs-253D-26reserved-3D0%26d%3DDwMGaQ%26c%3Djf_iaSHvJObTbx-siA1ZOg%26r%3DgkRZBtsmKeGPCOlAIRJoOA%26m%3Dc3lYikOfd2-4q_nd_qMnJ4gXKIuKuxxoJRxIrIZc3Hw%26s%3DlhWK6MIAPUmU4rsIhtD7P7EgacPwfGk17SvpQdMJogc%26e%3D&data=02%7C01%7Cbrsneed%40ebay.com%7Cebd9669255614ce4dccc08d4efef218c%7C46326bff992841a0baca17c16c94ea99%7C0%7C0%7C636397257717072726&sdata=jJucdx3j9pb2ylcsHYaVAtze%2B%2BQWr%2F%2Bm2GpBRlHaBTk%3D&reserved=0"><span style="font-size:10.0pt;font-family:"Courier New"">https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Dcorelibs-2Ddev&d=DwIGaQ&c=jf_iaSHvJObTbx-siA1ZOg&r=gkRZBtsmKeGPCOlAIRJoOA&m=ViDSVPImta3StTVAcktby2PMF_-du5itzz47jo-tNHg&s=zRuNQ3NLxpfhFBewRTkoMWZnpvHlm6Ja-ot9_pwAgqI&e=</span></a><span style="font-size:10.0pt;font-family:"Courier New"">
</span><br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<o:p></o:p></p>
</div>
</body>
</html>