Re: [swift-corelibs-dev] TimeZone database

2017-07-06 Thread Youming Lin via swift-corelibs-dev
We were seeing this on Travis too. Specifically, on a Travis matrix build
using Swift 3.1.1 on a Ubuntu 16.04 docker image running inside a Travis
14.04 VM.

The issue was specific to the Ubuntu 16.04 docker image; when I tested in
Ubuntu 16.04 OS as a guest VM, the issue went away.

Thanks,

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin



From:   Tony Parker via swift-corelibs-dev

To: Ian Partridge 
Cc: swift-corelibs-dev 
Date:   07/06/2017 10:31 AM
Subject:Re: [swift-corelibs-dev] TimeZone database
Sent by:[email protected]



Yes, we’re discussing this one internally too and trying to figure out what
the right answer is. Maybe the best solution for now is to find a good
mechanism to check the underlying version of the OS and split it out into a
function as you suggest.

- Tony

  On Jul 6, 2017, at 7:37 AM, Ian Partridge via swift-corelibs-dev <
  [email protected]> wrote:

  Good shout Simon, you are right.  I'm on Sierra.  Compare and
  contrast:

  
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/tzfile.h

  #define TZDIR   "/usr/share/zoneinfo"

  
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/tzfile.h

  #define TZDIR   "/var/db/timezone/zoneinfo"

  so I guess if I installed the High Sierra beta it would work OK.

  I hacked CF to force it to use /usr/share/zoneinfo and TestFoundation
  is much happier, but that's not a solution.

  On 6 July 2017 at 15:20, Simon Evans  wrote:
Ian

I also saw this error, I think its because the TZDIR is
different in the headers shipped with Xcode 9. Maybe the
location of the timezone directory was moved between Sierra and
High Sierra. What version of macOS are you testing on?

If it has indeed moved between 10.12 and 10.13 it may require a
runtime version check to dynamically return TZDIR.

Simon


  On 6 Jul 2017, at 15:09, Ian Partridge via
  swift-corelibs-dev  wrote:

  Hi,

  I'm seeing quite a lot of tests failing when running the
  TestFoundation target in Xcode.  The failures are
  timezone related.
  Most simply, the code

  let timeZone = TimeZone(abbreviation: "GMT")

  is returning nil.

  Walking through the CF code which sets things up, it
  seems to be
  trying to read the timezone database from
  /var/db/timezone/zoneinfo/zone.tab which doesn't exist on
  my macOS
  system.

  /usr/share/zoneinfo/zone.tab is there and seems to be the
  right
  location (?), but CF is picking up TZDIR from tzfile.h
  which says:

  #define TZDIR   "/var/db/timezone/zoneinfo"

  Any thoughts?  I feel like I'm missing something obvious
  and have gone
  too far down the rabbit hole.

  --
  Ian Partridge
  ___
  swift-corelibs-dev mailing list
  [email protected]
  https://lists.swift.org/mailman/listinfo/swift-corelibs-dev




  --
  Ian Partridge
  ___
  swift-corelibs-dev mailing list
  [email protected]
  https://lists.swift.org/mailman/listinfo/swift-corelibs-dev
___
swift-corelibs-dev mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev


___
swift-corelibs-dev mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev


Re: [swift-corelibs-dev] TimeZone database

2017-07-06 Thread Youming Lin via swift-corelibs-dev
That's odd. Maybe my ubuntu:16.04 image is outdated or something, but here
are my outputs:

ylin@youming-mbpr:~/Swift/Kitura-Markdown$ docker run -it --rm ubuntu:16.04
find /usr -name zone.tab
ylin@youming-mbpr:~/Swift/Kitura-Markdown$ docker run -it --rm ubuntu:14.04
find /usr -name zone.tab
/usr/share/zoneinfo/zone.tab

The file is found in ubuntu:14.04 but not in ubuntu:16.04.

Here are my images:

ylin@youming-mbpr:~/Swift/Kitura-Markdown$ docker images
REPOSITORY  TAG IMAGE IDCREATED
SIZE
ubuntu  16.04   7b9b13f7b9c04 weeks ago
118MB
ubuntu  14.04   132b7427a3b44 weeks ago
188MB

Thanks,

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin



From:   Alex Blewitt 
To: Tony Parker 
Cc: Youming Lin , Ian Partridge
, swift-corelibs-dev

Date:   07/06/2017 01:42 PM
Subject:Re: [swift-corelibs-dev] TimeZone database
Sent by:[email protected]



It looks like it's /usr/share/zoneinfo on all Ubuntu versions:

alblue.local[~]$ docker run -it --rm ubuntu:14.04 find /usr -name zone.tab
/usr/share/zoneinfo/zone.tab
alblue.local[~]$ docker run -it --rm ubuntu:16.04 find /usr -name zone.tab
/usr/share/zoneinfo/zone.tab
alblue.local[~]$ docker run -it --rm ubuntu:16.10 find /usr -name zone.tab
/usr/share/zoneinfo/zone.tab

This is the same that's coming from CFTimeZone.c:

https://github.com/apple/swift-corelibs-foundation/blob/2611dcd0d9b91fecace537838294bd85f0220503/CoreFoundation/NumberDate.subproj/CFTimeZone.c#L36-L39

Is it possible that the MacOS header is being included and defining TZDIR
before the CFTimeZone.c file is compiled?

Alex

  On 6 Jul 2017, at 19:22, Tony Parker via swift-corelibs-dev <
  [email protected]> wrote:

  Is the path to zoneinfo different on the Ubuntu docker image?

  - Tony

On Jul 6, 2017, at 9:36 AM, Youming Lin 
wrote:



We were seeing this on Travis too. Specifically, on a Travis
matrix build using Swift 3.1.1 on a Ubuntu 16.04 docker image
running inside a Travis 14.04 VM.

The issue was specific to the Ubuntu 16.04 docker image; when I
tested in Ubuntu 16.04 OS as a guest VM, the issue went away.

Thanks,

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin

Tony Parker via swift-corelibs-dev ---07/06/2017
10:31:15 AM---Yes, we’re discussing this one internally too and
trying to figure out what the right answer is. May

From: Tony Parker via swift-corelibs-dev <
[email protected]>
To: Ian Partridge 
Cc: swift-corelibs-dev 
Date: 07/06/2017 10:31 AM
Subject: Re: [swift-corelibs-dev] TimeZone database
Sent by: [email protected]





Yes, we’re discussing this one internally too and trying to
figure out what the right answer is. Maybe the best solution
for now is to find a good mechanism to check the underlying
version of the OS and split it out into a function as you
suggest.

- Tony
On Jul 6, 2017, at 7:37 AM, Ian Partridge via
swift-corelibs-dev 
wrote:

Good shout Simon, you are right. I'm on Sierra.
Compare and contrast:


/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/tzfile.h

#define TZDIR "/usr/share/zoneinfo"


/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/tzfile.h

#define TZDIR "/var/db/timezone/zoneinfo"

so I guess if I installed the High Sierra beta it
would work OK.

I hacked CF to force it to use /usr/share/zoneinfo
and TestFoundation
is much happier, but that's not a solution.

On 6 July 2017 at 15:20, Simon Evans 
wrote:
Ian

I also saw this error, I think its
because the TZDIR is different in the
headers shipped with Xcode 9. Maybe the
location of the timezone directory was
moved between Sierra and High Sierra.
What version of macOS are you testing
on?


Re: [swift-corelibs-dev] TimeZone database

2017-07-06 Thread Youming Lin via swift-corelibs-dev
Thanks for pointing me to the package. Turns out it was intentional:
https://github.com/docker-library/official-images/issues/2863

A caveat to Swift developers using official Docker Ubuntu images in the
future.

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin



From:   Simon Evans 
To: Youming Lin 
Cc: Alex Blewitt , Ian Partridge
, swift-corelibs-dev

Date:   07/06/2017 03:20 PM
Subject:Re: [swift-corelibs-dev] TimeZone database



Looks like timezone files are in the ‘tzdata’ package. Maybe it got
uninstalled or was never installed as part of the base. An ‘apt-get install
tzdata’ might fix it.

Simon

  On 6 Jul 2017, at 20:20, Youming Lin via swift-corelibs-dev <
  [email protected]> wrote:



  That's odd. Maybe my ubuntu:16.04 image is outdated or something, but
  here are my outputs:

  ylin@youming-mbpr:~/Swift/Kitura-Markdown$ docker run -it --rm
  ubuntu:16.04 find /usr -name zone.tab
  ylin@youming-mbpr:~/Swift/Kitura-Markdown$ docker run -it --rm
  ubuntu:14.04 find /usr -name zone.tab
  /usr/share/zoneinfo/zone.tab

  The file is found in ubuntu:14.04 but not in ubuntu:16.04.

  Here are my images:

  ylin@youming-mbpr:~/Swift/Kitura-Markdown$ docker images
  REPOSITORY TAG IMAGE ID CREATED SIZE
  ubuntu 16.04 7b9b13f7b9c0 4 weeks ago 118MB
  ubuntu 14.04 132b7427a3b4 4 weeks ago 188MB

  Thanks,

  Youming Lin
  IBM Cloud, Swift@IBM, Kitura developer
  Austin, TX
  GitHub: @youming-lin

  Alex Blewitt ---07/06/2017 01:42:22 PM---It looks like
  it's /usr/share/zoneinfo on all Ubuntu versions: alblue.local[~]$
  docker run -it --rm

  From: Alex Blewitt 
  To: Tony Parker 
  Cc: Youming Lin , Ian Partridge ,
  swift-corelibs-dev 
  Date: 07/06/2017 01:42 PM
  Subject: Re: [swift-corelibs-dev] TimeZone database
  Sent by: [email protected]





  It looks like it's /usr/share/zoneinfo on all Ubuntu versions:

  alblue.local[~]$ docker run -it --rm ubuntu:14.04 find /usr -name
  zone.tab
  /usr/share/zoneinfo/zone.tab
  alblue.local[~]$ docker run -it --rm ubuntu:16.04 find /usr -name
  zone.tab
  /usr/share/zoneinfo/zone.tab
  alblue.local[~]$ docker run -it --rm ubuntu:16.10 find /usr -name
  zone.tab
  /usr/share/zoneinfo/zone.tab

  This is the same that's coming from CFTimeZone.c:

  
https://github.com/apple/swift-corelibs-foundation/blob/2611dcd0d9b91fecace537838294bd85f0220503/CoreFoundation/NumberDate.subproj/CFTimeZone.c#L36-L39


  Is it possible that the MacOS header is being included and defining
  TZDIR before the CFTimeZone.c file is compiled?

  Alex
  On 6 Jul 2017, at 19:22, Tony Parker via
  swift-corelibs-dev  wrote:

  Is the path to zoneinfo different on the Ubuntu docker
  image?

  - Tony
  On Jul 6, 2017, at 9:36 AM, Youming Lin <
  [email protected]> wrote:


  We were seeing this on Travis too.
  Specifically, on a Travis matrix build using
  Swift 3.1.1 on a Ubuntu 16.04 docker image
  running inside a Travis 14.04 VM.

  The issue was specific to the Ubuntu 16.04
  docker image; when I tested in Ubuntu 16.04
  OS as a guest VM, the issue went away.

  Thanks,

  Youming Lin
  IBM Cloud, Swift@IBM, Kitura developer
  Austin, TX
  GitHub: @youming-lin

  Tony Parker via
  swift-corelibs-dev ---07/06/2017 10:31:15
  AM---Yes, we’re discussing this one
  internally too and trying to figure out what
  the right answer is. May

  From: Tony Parker via swift-corelibs-dev <
  [email protected]>
  To: Ian Partridge 
  Cc: swift-corelibs-dev <
  [email protected]>
  Date: 07/06/2017 10:31 AM
  Subject: Re: [swift-corelibs-dev] TimeZone
  database
  Sent by: [email protected]






  Yes, we’re discussing this one internally too
  and trying to figure out what the right
  a

Re: [swift-corelibs-dev] Adding type conversion capabilities to JSONencode/decode

2017-08-30 Thread Youming Lin via swift-corelibs-dev
One downside I see is that the encoder wouldn't know if this specific field
was originally a number instead of a string. If the same Codable struct is
used for GET and POST, for example, the post-encode JSON string could be
invalid because the server expects a number instead of a string for that
field.

An explicit mapping of JSON value type to Codable ivar type would be
needed, but this can create validation issues because while all numbers can
be converted to strings (decode is OK), not all strings can be converted to
numbers (encode is not OK).

Thanks,

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin



From:   "Sneed, Brandon via swift-corelibs-dev"

To: "[email protected]" 
Date:   08/30/2017 01:00 PM
Subject:[swift-corelibs-dev] Adding type conversion capabilities to
JSONencode/decode
Sent by:[email protected]



Hi everyone,

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.

Type type conversion, I mean given this JSON payload:

{
"name": "Endeavor”,
"abv": 8.9,
"brewery": "Saint Arnold”,
"style": "ipa"
}

and a struct defined as:

struct Beer: Codable {
let name: String
let abv: String
let brewery: String
let style: BeerStyle
}

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:

1.   It’s defensive; service types can change without causing my
application to crash.
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.

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.

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:

struct Beer: Codable, CodingConvertible {
let name: String
let abv: String
let brewery: String
let style: BeerStyle
}

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.

Another option would be to box each type, like so:

struct Beer: Codable {
let name: String
let abv: Convertible
let brewery: String
let style: BeerStyle
}

This seems tedious for developers, but would show which types are being
converted.  It does however seriously weaken benefit #1 above.

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.

I’m very open to alternatives, other ideas, or anything else you might have
to say on the subject.  Thanks for reading!



Brandon Sneed



 ___
swift-corelibs-dev mailing list
[email protected]
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=utPJ8lPG7RUnVBM2S83fXgDyBRVtivz1iTkYslFYIKI&s=JYMXmKeoK1ETGzoGDIMdIL6M1MNEo8ij571lOudNSWw&e=



___
swift-corelibs-dev mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev


Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode

2017-08-30 Thread Youming Lin via swift-corelibs-dev
Brandon

>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.

You can override the default behavior with your own custom init(from:)
implementation for your Codable struct:
https://developer.apple.com/documentation/swift/decodable/2894081-init

You can check Foundation source code (i.e., the URL struct) on how this can
be implemented.

Thanks,

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin



From:   "Sneed, Brandon via swift-corelibs-dev"

To: Tony Parker 
Cc: "[email protected]" 
Date:   08/30/2017 03:07 PM
Subject:Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode
Sent by:[email protected]



Hi Tony,

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.

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 *another* 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.


Brandon Sneed

From:  on behalf of Tony Parker

Date: Wednesday, August 30, 2017 at 11:30 AM
To: "Sneed, Brandon" 
Cc: Itai Ferber , "[email protected]"

Subject: Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode

I’m still not convinced that we should actually provide such a strategy.

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.

JSON has very few types already. I’m not sure we want to blur the line
between numbers and strings automatically…

- Tony


  On Aug 30, 2017, at 11:24 AM, Sneed, Brandon via swift-corelibs-dev <
  [email protected]> wrote:

  Hi Itai,

  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.

  Thanks!


  Brandon Sneed

  From:  on behalf of Itai Ferber 
  Date: Wednesday, August 30, 2017 at 11:22 AM
  To: "Sneed, Brandon" 
  Cc: "[email protected]" 
  Subject: Re: [swift-corelibs-dev] Adding type conversion capabilities
  to JSON encode/decode

  Hi Brandon,
  Thanks for looking at this! We’ve got plans internally to potentially
  add a strategy to JSONEncoder/JSONDecoder to allow lenient
  conversions like this — i.e. implicitly stringify numbers (or parse
  them from string input), among some others.
  This would be opt-in for consumers of JSONDecoder while not requiring
  any special annotations on Codable types.
  — Itai
  On 30 Aug 2017, at 10:59, Sneed, Brandon via swift-corelibs-dev
  wrote:
  Hi everyone,

  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.

  Type type conversion, I mean given this JSON payload:

  {
  "name": "Endeavor”,
  "abv": 8.9,
  "brewery": "Saint Arnold”,
  "style": "ipa"
  }

  and a struct defined as:

  struct Beer: Codable {
  let name: String
  let abv: String
  let brewery: String
  let style: BeerStyle
  }

  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:

  1.   It’s defensive; service types can change without causing my
  application to crash.
  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.

  The argument against it that I’ve heard is generally “it’s a service
  bug, mak

Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode

2017-08-30 Thread Youming Lin via swift-corelibs-dev
Brandon

I cooked up a simple example and it works as expected.

ylin@youming-mbpr:~/Swift/Configuration$ swift
Welcome to Apple Swift version 4.0-dev (LLVM 2dedb62a0b, Clang b9d76a314c,
Swift 0899bd328a). Type :help for assistance.
  1> import Foundation
  2> struct A: Codable {
  3. var integer: Int
  4.
  5. public init(integer: Int) {
  6. self.integer = integer
  7. }
  8.
  9. public init(from decoder: Decoder) throws {
 10. print("Custom decoder")
 11. let container = try decoder.container(keyedBy:
CodingKeys.self)
 12. integer = try container.decode(Int.self, forKey: .integer)
 13. }
 14. }
 15.
 16. try! JSONDecoder().decode(A.self, from: JSONEncoder().encode(A
(integer: 42)))
Custom decoder
$R0: A = {
  integer = 42
}

You should be able to implement your custom init to convert the number into
a string and JSONDecoder should use that automatically.

Thanks,

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin



From:   "Sneed, Brandon" 
To: Youming Lin 
Cc: Tony Parker ,
"[email protected]" ,
"[email protected]"

Date:   08/30/2017 04:14 PM
Subject:Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode



Thanks Youming,

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.

Any insight is appreciated.

Thanks!



Brandon Sneed

From: Youming Lin 
Date: Wednesday, August 30, 2017 at 1:18 PM
To: "Sneed, Brandon" 
Cc: Tony Parker , "[email protected]"
, "[email protected]"

Subject: Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode



Brandon

>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.

You can override the default behavior with your own custom init(from:)
implementation for your Codable struct:
https://developer.apple.com/documentation/swift/decodable/2894081-init

You can check Foundation source code (i.e., the URL struct) on how this can
be implemented.

Thanks,

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin

nactive hide details for "Sneed, Brandon via swift-corelibs-dev" ---08/30
"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

From: "Sneed, Brandon via swift-corelibs-dev"

To: Tony Parker 
Cc: "[email protected]" 
Date: 08/30/2017 03:07 PM
Subject: Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode
Sent by: [email protected]




Hi Tony,

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.

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 *another* 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.


Brandon Sneed

From:  on behalf of Tony Parker

Date: Wednesday, August 30, 2017 at 11:30 AM
To: "Sneed, Brandon" 
Cc: Itai Ferber , "[email protected]"

Subject: Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode

I’m still not convinced that we should actually provide such a strategy.

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.

JSON has very few types already. I’m not sure we want to blur the line
between numbers and strings automatically…

- Tony
On Aug 30, 2017, at 11:24 AM, Sneed, Brandon via
swift-corelibs-dev  wrote:

Hi Itai,

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 hav

Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode

2017-08-30 Thread Youming Lin via swift-corelibs-dev
Brandon

Sorry, I didn't realize you want it on the String type since you used other
string ivars in your example as well.

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.

A custom Codable type to represent number-equivalent strings is a better
solution I think.

Thanks,

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin



From:   "Sneed, Brandon" 
To: Youming Lin 
Cc: Tony Parker ,
"[email protected]" ,
"[email protected]"

Date:   08/30/2017 04:42 PM
Subject:Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode



Thanks Youming,

That’s not quite what I meant.  I may have misinterpreted what Tony was
saying though.

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:

import Cocoa

let jsonString = "{" +
"\"name\": \"Endeavor\"," +
"\"abv\": 8.9," +
"\"brewery\": \"Saint Arnold\"," +
"\"style\": \"ipa\"}"

struct Beer: Codable {
let name: String
let abv: String
let brewery: String
let style: String
}

extension String {
init(from decoder: Decoder) throws {
print("i got hit.")
let value = try decoder.singleValueContainer().decode(String.self)
self.init(value)
}
}

let jsonData = jsonString.data(using: .utf8)
let decoder = JSONDecoder()
let beer = try! decoder.decode(Beer.self, from: jsonData!)

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



From: Youming Lin 
Date: Wednesday, August 30, 2017 at 2:35 PM
To: "Sneed, Brandon" 
Cc: Tony Parker , "[email protected]"
, "[email protected]"

Subject: Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode



Brandon

I cooked up a simple example and it works as expected.

ylin@youming-mbpr:~/Swift/Configuration$ swift
Welcome to Apple Swift version 4.0-dev (LLVM 2dedb62a0b, Clang b9d76a314c,
Swift 0899bd328a). Type :help for assistance.
1> import Foundation
2> struct A: Codable {
3. var integer: Int
4.
5. public init(integer: Int) {
6. self.integer = integer
7. }
8.
9. public init(from decoder: Decoder) throws {
10. print("Custom decoder")
11. let container = try decoder.container(keyedBy: CodingKeys.self)
12. integer = try container.decode(Int.self, forKey: .integer)
13. }
14. }
15.
16. try! JSONDecoder().decode(A.self, from: JSONEncoder().encode(A(integer:
42)))
Custom decoder
$R0: A = {
integer = 42
}

You should be able to implement your custom init to convert the number into
a string and JSONDecoder should use that automatically.

Thanks,

Youming Lin
IBM Cloud, Swift@IBM, Kitura developer
Austin, TX
GitHub: @youming-lin

nactive hide details for "Sneed, Brandon" ---08/30/2017 04:14:57 PM---Tha
"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

From: "Sneed, Brandon" 
To: Youming Lin 
Cc: Tony Parker , "[email protected]"
, "[email protected]"

Date: 08/30/2017 04:14 PM
Subject: Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode




Thanks Youming,

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.

Any insight is appreciated.

Thanks!



Brandon Sneed

From: Youming Lin 
Date: Wednesday, August 30, 2017 at 1:18 PM
To: "Sneed, Brandon" 
Cc: Tony Parker , "[email protected]"
, "[email protected]"

Subject: Re: [swift-corelibs-dev] Adding type conversion capabilities to
JSON encode/decode


Brandon

>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.

You can override the default behavior with your own custom init(from:)
implementation for your Codable struct:
https://develope