JSON not able to unmarshal net.IP

1,262 views
Skip to first unread message

gta

unread,
Mar 15, 2013, 7:07:43 AM3/15/13
to golan...@googlegroups.com
Hi,
I am using a JSON file as configuration file and I found out that a net.IP can be marshaled but not unmarshaled: http://play.golang.org/p/o-7AnROIPq.
Also the marshaled net.IP is not really readable, (base64 encoded?) which was kind of the point in my use case.

Bug or feature?

Would it be better to have the IP use the String() version?
And the type in the standard library containing a net.IP (TCPAddr, UDPAddr, etc) be able to marshal and unmarshal it like "127.0.0.1:1234"?

Ciao.


Giacomo



Jan Mercl

unread,
Mar 15, 2013, 7:11:29 AM3/15/13
to gta, golang-nuts

gta

unread,
Mar 15, 2013, 8:10:34 AM3/15/13
to golan...@googlegroups.com, gta
Yeah that works, maybe I should have been more specific on my use case.
I am serializing a struct containing a net.IP, in this case net.UDPAddr, so I cannot make any cast. 


-j

Jan Mercl

unread,
Mar 15, 2013, 8:26:19 AM3/15/13
to gta, golang-nuts
On Fri, Mar 15, 2013 at 1:10 PM, gta <giacomo...@gmail.com> wrote:

> Yeah that works, maybe I should have been more specific on my use case.
> I am serializing a struct containing a net.IP, in this case net.UDPAddr, so
> I cannot make any cast.
> http://play.golang.org/p/M6M3Hqjkkt

- There is no casting in Go. It's conversion and it is not the same thing.
- There are several options how to handle it, a simple one is e.g.:
http://play.golang.org/p/LWSZa9Wb5L

-j

gta

unread,
Mar 15, 2013, 8:48:35 AM3/15/13
to golan...@googlegroups.com, gta


On Friday, 15 March 2013 13:26:19 UTC+1, Jan Mercl wrote:
On Fri, Mar 15, 2013 at 1:10 PM, gta <giacomo...@gmail.com> wrote:

> Yeah that works, maybe I should have been more specific on my use case.
> I am serializing a struct containing a net.IP, in this case net.UDPAddr, so
> I cannot make any cast.
> http://play.golang.org/p/M6M3Hqjkkt

- There is no casting in Go. It's conversion and it is not the same thing.
 
Slip of the tongue :) 

- There are several options how to handle it, a simple one is e.g.:
http://play.golang.org/p/LWSZa9Wb5L
 
I see, but my main point is: should't t work out of the box?

Also possibly very stupid question: why does X works and net.UDPAddr does not? 
Is it because net.UDPAddr.IP is a named type? 
Am I missing something?

Thanks for your time.

Giacomo.


-j

Kevin D

unread,
Mar 15, 2013, 5:17:59 PM3/15/13
to golan...@googlegroups.com, gta
Maybe someone could give a better answer to this, but it's because in the library it specifically restricts using another type that is defined on []byte. I'm not entirely sure why, but this is the code in literalStore that prevents it:

if v.Type() != byteSliceType {
  d.saveError(&UnmarshalTypeError{"string", v.Type()})
  break
}

Here is my test code that fails:

If you change type Test to anything other than []byte (like []int8), then it works fine (although it's not serialized as base64).

gta

unread,
Mar 16, 2013, 4:29:20 AM3/16/13
to golan...@googlegroups.com, gta
Thanks for the replies folks. 
I guess I have to figure out a way to do it as Jan suggested, cannot change the types in the standard library.

Ciao.

Giacomo

gta

unread,
Mar 19, 2013, 8:04:41 AM3/19/13
to golan...@googlegroups.com, gta
Actually I am still thinking about it and I would like to scratch this itch of mine.
I am willing to submit a patch, if it is not too late for Go 1.1, as soon as I have time.
I believe the dev team has more important matters to attent to but the change should be small enough.

I was thinking to make net.IP implement json.Marshaler and json.Unmarshaler, MarshalJSON() will call IP.String() and UnmarshlJSON() will call net.ParseIP(), somehow mirroring time.Time marshaling/unmarshaling.

The test could be to marshal/unmarshal a struct containing a net.UDPAddr/TCPAddr/IPAdd, both IPv4 and IPv6.

Should I open an issue?
Am I doing it right?
Reply all
Reply to author
Forward
0 new messages