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

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