github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/talks/2015/json/unmarshaler1.go (about)

     1  // +build OMIT
     2  
     3  package main
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/json"
     8  	"fmt"
     9  	"log"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  const input = `
    15  {
    16  	"name": "Gopher",
    17  	"birthdate": "2009/11/10",
    18  	"shirt-size": "XS"
    19  }
    20  `
    21  
    22  type Person struct {
    23  	Name string
    24  	Born time.Time
    25  	Size ShirtSize
    26  }
    27  
    28  type ShirtSize byte
    29  
    30  const (
    31  	NA ShirtSize = iota
    32  	XS
    33  	S
    34  	M
    35  	L
    36  	XL
    37  )
    38  
    39  func (ss ShirtSize) String() string {
    40  	s, ok := map[ShirtSize]string{XS: "XS", S: "S", M: "M", L: "L", XL: "XL"}[ss]
    41  	if !ok {
    42  		return "invalid ShirtSize"
    43  	}
    44  	return s
    45  }
    46  
    47  func ParseShirtSize(s string) (ShirtSize, error) {
    48  	ss, ok := map[string]ShirtSize{"XS": XS, "S": S, "M": M, "L": L, "XL": XL}[s]
    49  	if !ok {
    50  		return NA, fmt.Errorf("invalid ShirtSize %q", s)
    51  	}
    52  	return ss, nil
    53  }
    54  
    55  func (p *Person) UnmarshalJSON(data []byte) error {
    56  	var aux struct {
    57  		Name string
    58  		Born string `json:"birthdate"`
    59  		Size string `json:"shirt-size"`
    60  	}
    61  
    62  	dec := json.NewDecoder(bytes.NewReader(data)) // HL
    63  	if err := dec.Decode(&aux); err != nil {
    64  		return fmt.Errorf("decode person: %v", err)
    65  	}
    66  	p.Name = aux.Name
    67  	// ... rest of function omitted ...
    68  	born, err := time.Parse("2006/01/02", aux.Born)
    69  	if err != nil {
    70  		return fmt.Errorf("invalid date: %v", err)
    71  	}
    72  	p.Born = born
    73  	p.Size, err = ParseShirtSize(aux.Size)
    74  	return err
    75  }
    76  
    77  func main() {
    78  	var p Person
    79  	dec := json.NewDecoder(strings.NewReader(input))
    80  	if err := dec.Decode(&p); err != nil {
    81  		log.Fatalf("parse person: %v", err)
    82  	}
    83  	fmt.Println(p)
    84  }