I'm trying to use the json.Unmarshaler interface to unmarshal a UUID into a uuid.UUID field on a struct. I created a custom type called myUUID and everything works until I try to access methods that are normally on uuid.UUID. How can I handle this? I'm relatively new to Go, so maybe I just don't fully understand custom types just yet.
package main
import (
"encoding/json"
"errors"
"fmt"
"code.google.com/p/go-uuid/uuid"
)
var jsonstring = `
{
"uuid": "273b62ad-a99d-48be-8d80-ccc55ef688b4"
}
`
type myUUID uuid.UUID
type Data struct {
uuid myUUID
}
func (u *myUUID) UnmarshalJson(b []byte) error {
id := uuid.Parse(string(b[:]))
if id == nil {
return errors.New("Could not parse UUID")
}
*u = myUUID(id)
return nil
}
func main() {
d := new(Data)
err := json.Unmarshal([]byte(jsonstring), &d)
if err != nil {
fmt.Printf("%s", err)
}
fmt.Println(d.uuid.String())
}
You might want to make sure your myuuid
variable is visible/exported in the Data struct
: as in "public".
Same for the type alias MyUUID
(instead of myUUID
)
type MyUUID uuid.UUID
type Data struct {
Uuid MyUUID
}
From JSON and Go:
The json package only accesses the exported fields of struct types (those that begin with an uppercase letter).
As commented by Ainar G, the style guide also recommends:
Words in names that are initialisms or acronyms (e.g. "
URL
" or "NATO
") have a consistent case.
For example, "URL
" should appear as "URL
" or "url
" (as in "urlPony
", or "URLPony
"), never as "Url
". Here's an example:ServeHTTP
notServeHttp
.This rule also applies to "
ID
" when it is short for "identifier," so write "appID
" instead of "appId
".
In your case, that would mean:
type Data struct {
UUID MyUUID
}
Go's custom types don't inherit methods. I refactored the code using a custom struct and attaching an UnmarshalJSON.
import (
"errors"
"strings"
"github.com/pborman/uuid"
)
type ServiceID struct {
UUID uuid.UUID
}
type Meta struct {
Name string `json:"name"`
Version string `json:"version"`
SID *ServiceID `json:"UUID"`
}
func (self *ServiceID) UnmarshalJSON(b []byte) error {
s := strings.Trim(string(b), "\"")
self.UUID = uuid.Parse(s)
if self.UUID == nil {
return errors.New("Could not parse UUID")
}
return nil
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With