Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MarshalJSON on array of structs with non standard field in Go

Tags:

go

I have the following types:

type IPFilePair struct {
    IP net.IP
    FileName string
}

type IPFilePairs []*IPFilePair

I'm trying to marshal the JSON of this using json.Marshal(sample_ipfilepairs) but because IP isn't a string, it changes it into something strange.

What is the proper way to make the JSON of this output IP as a string?

like image 984
Breathtender Avatar asked Apr 14 '13 06:04

Breathtender


1 Answers

I think if you have access to the definition of IPFilePair, creating local typedef of net.IP that you add MarshanJSON() to is the way to go:

package main

import (
    "encoding/json"
    "net"
    "fmt"
)

type netIP net.IP

type IPFilePair struct {
    IP netIP
    FileName string
}

type IPFilePairs []*IPFilePair

func (ip netIP) MarshalJSON() ([]byte, error) {
    return json.Marshal(net.IP(ip).String())
}

func main() {
    pair1 := IPFilePair{netIP{127, 0, 0, 1}, "file1"}
    pair2 := IPFilePair{netIP{127, 0, 0, 2}, "file2"}
    sample_ipfilepairs := IPFilePairs{&pair1, &pair2}

    b, _ := json.Marshal(sample_ipfilepairs)
    fmt.Println(string(b))
}

This outputs:

[{"IP":"127.0.0.1","FileName":"file1"},{"IP":"127.0.0.2","FileName":"file2"}]

Of course, if you ever need to unmarshal that back into the same Go data structure, you'll want to implement UnmarshalJSON() on netIP using net.ParseIP.

I'm certainly curious if anyone knows of an easier way to accomplish this.

like image 69
Darshan Rivka Whittle Avatar answered Sep 18 '22 22:09

Darshan Rivka Whittle