1// Copyright (c) 2021, Peter Ohler, All rights reserved. 2 3package oj_test 4 5import ( 6 "fmt" 7 8 "github.com/ohler55/ojg" 9 "github.com/ohler55/ojg/alt" 10 "github.com/ohler55/ojg/oj" 11) 12 13// Encode and decode slice of interfaces. 14 15type Animal interface { 16 Kind() string 17} 18 19type Dog struct { 20 Size string 21} 22 23func (d *Dog) Kind() string { 24 return fmt.Sprintf("%s dog", d.Size) 25} 26 27type Cat struct { 28 Color string 29} 30 31func (c *Cat) Kind() string { 32 return fmt.Sprintf("%s cat", c.Color) 33} 34 35func ExampleUnmarshal_interface() { 36 pets := []Animal{&Dog{Size: "big"}, &Cat{Color: "black"}} 37 38 // Encode and use a create key to identify the encoded type. 39 b, err := oj.Marshal(pets, &ojg.Options{CreateKey: "^", Sort: true}) 40 if err != nil { 41 panic(err) 42 } 43 // Sort the object members in the output for repeatability. 44 fmt.Printf("as JSON: %s\n", b) 45 46 // Create a new Recomposer. This can be use over and over again. Register 47 // the types with a nil creation function to let reflection do the work 48 // since the types are exported. 49 var r *alt.Recomposer 50 if r, err = alt.NewRecomposer("^", map[interface{}]alt.RecomposeFunc{&Dog{}: nil, &Cat{}: nil}); err != nil { 51 panic(err) 52 } 53 var result interface{} 54 if err = oj.Unmarshal(b, &result, r); err != nil { 55 panic(err) 56 } 57 list, _ := result.([]interface{}) 58 for _, item := range list { 59 animal, _ := item.(Animal) 60 fmt.Printf(" %s\n", animal.Kind()) 61 } 62 // Unmarshal with a typed target. 63 var animals []Animal 64 if err = oj.Unmarshal(b, &animals, r); err != nil { 65 panic(err) 66 } 67 fmt.Println("Unmarshal into a target struct") 68 for _, animal := range animals { 69 fmt.Printf(" %T - %s\n", animal, animal.Kind()) 70 } 71 72 // Output: 73 // as JSON: [{"^":"Dog","size":"big"},{"^":"Cat","color":"black"}] 74 // big dog 75 // black cat 76 // Unmarshal into a target struct 77 // *oj_test.Dog - big dog 78 // *oj_test.Cat - black cat 79} 80