4 ms·
the json.NewDecoder stuff does still trigger unmarshals of the types in the struct and such: i.e. package main import ( "bytes" "encodin
by Vendan 8y ago
the json.NewDecoder stuff does still trigger unmarshals of the types in the struct and such: i.e.
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
)
func main() {
fmt.Println("Hello, playground")
var p Post
err := json.Unmarshal([]byte(`{"title": "test"}`), &p)
fmt.Println(err, p)
err = json.Unmarshal([]byte(`{"title2": "test"}`), &p)
fmt.Println(err, p)
err = json.Unmarshal([]byte(`{}`), &p)
fmt.Println(err, p)
err = json.Unmarshal([]byte(`{"title": "long test"}`), &p)
fmt.Println(err, p)
}
type Post struct {
Title ShortTitle `json:"title"`
}
func (v *Post) UnmarshalJSON(b []byte) error {
dec := json.NewDecoder(bytes.NewReader(b))
required := map[string]struct{}{
"title": struct{}{},
}
tok, err := dec.Token()
if err != nil {
return err
}
if d, ok := tok.(json.Delim); !ok || d != '{' {
return errors.New("Expected object")
}
for {
tok, err := dec.Token()
if err != nil {
return err
}
if d, ok := tok.(json.Delim); ok && d == '}' {
break
}
switch tok {
case "title":
delete(required, "title")
err := dec.Decode(&v.Title)
if err != nil {
return err
}
default:
(*v) = Post{}
return errors.New(fmt.Sprintf("Unexpected field %s", tok))
}
}
if len(required) > 0 {
(*v) = Post{}
return errors.New(fmt.Sprintf("Missing %v required fields", len(required)))
}
return nil
}
type ShortTitle string
func (st *ShortTitle) UnmarshalJSON(b []byte) error {
var tmpst string
err := json.Unmarshal(b, &tmpst)
if err != nil {
return err
}
if len(tmpst) > 6 {
return errors.New("Title too long!")
}
*st = ShortTitle(tmpst)
return nil
}