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 }