<html 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="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)">
<style><!--
/* Font Definitions */
@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;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:Calibri;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        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-family:Calibri;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body bgcolor="white" lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt">Hi everyone,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Type type conversion, I mean given this JSON payload:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> "name": "Endeavor”,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> "abv": 8.9,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> "brewery": "Saint Arnold”,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> "style": "ipa"<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">and a struct defined as:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">struct Beer: Codable {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let name: String<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let abv: String<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let brewery: String<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let style: BeerStyle<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">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:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">1. It’s defensive; service types can change without causing my application to crash.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">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:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">struct Beer: Codable, CodingConvertible {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let name: String<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let abv: String<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let brewery: String<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let style: BeerStyle<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Another option would be to box each type, like so:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">struct Beer: Codable {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let name: String<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let abv: Convertible<String><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let brewery: String<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> let style: BeerStyle<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">This seems tedious for developers, but would show which types are being converted. It does however seriously weaken benefit #1 above.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">I’m very open to alternatives, other ideas, or anything else you might have to say on the subject. Thanks for reading!<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Brandon Sneed<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"> <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
</body>
</html>