...

Source file src/github.com/mitchellh/mapstructure/mapstructure_examples_test.go

Documentation: github.com/mitchellh/mapstructure

     1  package mapstructure
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  func ExampleDecode() {
     8  	type Person struct {
     9  		Name   string
    10  		Age    int
    11  		Emails []string
    12  		Extra  map[string]string
    13  	}
    14  
    15  	// This input can come from anywhere, but typically comes from
    16  	// something like decoding JSON where we're not quite sure of the
    17  	// struct initially.
    18  	input := map[string]interface{}{
    19  		"name":   "Mitchell",
    20  		"age":    91,
    21  		"emails": []string{"one", "two", "three"},
    22  		"extra": map[string]string{
    23  			"twitter": "mitchellh",
    24  		},
    25  	}
    26  
    27  	var result Person
    28  	err := Decode(input, &result)
    29  	if err != nil {
    30  		panic(err)
    31  	}
    32  
    33  	fmt.Printf("%#v", result)
    34  	// Output:
    35  	// mapstructure.Person{Name:"Mitchell", Age:91, Emails:[]string{"one", "two", "three"}, Extra:map[string]string{"twitter":"mitchellh"}}
    36  }
    37  
    38  func ExampleDecode_errors() {
    39  	type Person struct {
    40  		Name   string
    41  		Age    int
    42  		Emails []string
    43  		Extra  map[string]string
    44  	}
    45  
    46  	// This input can come from anywhere, but typically comes from
    47  	// something like decoding JSON where we're not quite sure of the
    48  	// struct initially.
    49  	input := map[string]interface{}{
    50  		"name":   123,
    51  		"age":    "bad value",
    52  		"emails": []int{1, 2, 3},
    53  	}
    54  
    55  	var result Person
    56  	err := Decode(input, &result)
    57  	if err == nil {
    58  		panic("should have an error")
    59  	}
    60  
    61  	fmt.Println(err.Error())
    62  	// Output:
    63  	// 5 error(s) decoding:
    64  	//
    65  	// * 'Age' expected type 'int', got unconvertible type 'string', value: 'bad value'
    66  	// * 'Emails[0]' expected type 'string', got unconvertible type 'int', value: '1'
    67  	// * 'Emails[1]' expected type 'string', got unconvertible type 'int', value: '2'
    68  	// * 'Emails[2]' expected type 'string', got unconvertible type 'int', value: '3'
    69  	// * 'Name' expected type 'string', got unconvertible type 'int', value: '123'
    70  }
    71  
    72  func ExampleDecode_metadata() {
    73  	type Person struct {
    74  		Name string
    75  		Age  int
    76  	}
    77  
    78  	// This input can come from anywhere, but typically comes from
    79  	// something like decoding JSON where we're not quite sure of the
    80  	// struct initially.
    81  	input := map[string]interface{}{
    82  		"name":  "Mitchell",
    83  		"age":   91,
    84  		"email": "foo@bar.com",
    85  	}
    86  
    87  	// For metadata, we make a more advanced DecoderConfig so we can
    88  	// more finely configure the decoder that is used. In this case, we
    89  	// just tell the decoder we want to track metadata.
    90  	var md Metadata
    91  	var result Person
    92  	config := &DecoderConfig{
    93  		Metadata: &md,
    94  		Result:   &result,
    95  	}
    96  
    97  	decoder, err := NewDecoder(config)
    98  	if err != nil {
    99  		panic(err)
   100  	}
   101  
   102  	if err := decoder.Decode(input); err != nil {
   103  		panic(err)
   104  	}
   105  
   106  	fmt.Printf("Unused keys: %#v", md.Unused)
   107  	// Output:
   108  	// Unused keys: []string{"email"}
   109  }
   110  
   111  func ExampleDecode_weaklyTypedInput() {
   112  	type Person struct {
   113  		Name   string
   114  		Age    int
   115  		Emails []string
   116  	}
   117  
   118  	// This input can come from anywhere, but typically comes from
   119  	// something like decoding JSON, generated by a weakly typed language
   120  	// such as PHP.
   121  	input := map[string]interface{}{
   122  		"name":   123,                      // number => string
   123  		"age":    "42",                     // string => number
   124  		"emails": map[string]interface{}{}, // empty map => empty array
   125  	}
   126  
   127  	var result Person
   128  	config := &DecoderConfig{
   129  		WeaklyTypedInput: true,
   130  		Result:           &result,
   131  	}
   132  
   133  	decoder, err := NewDecoder(config)
   134  	if err != nil {
   135  		panic(err)
   136  	}
   137  
   138  	err = decoder.Decode(input)
   139  	if err != nil {
   140  		panic(err)
   141  	}
   142  
   143  	fmt.Printf("%#v", result)
   144  	// Output: mapstructure.Person{Name:"123", Age:42, Emails:[]string{}}
   145  }
   146  
   147  func ExampleDecode_tags() {
   148  	// Note that the mapstructure tags defined in the struct type
   149  	// can indicate which fields the values are mapped to.
   150  	type Person struct {
   151  		Name string `mapstructure:"person_name"`
   152  		Age  int    `mapstructure:"person_age"`
   153  	}
   154  
   155  	input := map[string]interface{}{
   156  		"person_name": "Mitchell",
   157  		"person_age":  91,
   158  	}
   159  
   160  	var result Person
   161  	err := Decode(input, &result)
   162  	if err != nil {
   163  		panic(err)
   164  	}
   165  
   166  	fmt.Printf("%#v", result)
   167  	// Output:
   168  	// mapstructure.Person{Name:"Mitchell", Age:91}
   169  }
   170  
   171  func ExampleDecode_embeddedStruct() {
   172  	// Squashing multiple embedded structs is allowed using the squash tag.
   173  	// This is demonstrated by creating a composite struct of multiple types
   174  	// and decoding into it. In this case, a person can carry with it both
   175  	// a Family and a Location, as well as their own FirstName.
   176  	type Family struct {
   177  		LastName string
   178  	}
   179  	type Location struct {
   180  		City string
   181  	}
   182  	type Person struct {
   183  		Family    `mapstructure:",squash"`
   184  		Location  `mapstructure:",squash"`
   185  		FirstName string
   186  	}
   187  
   188  	input := map[string]interface{}{
   189  		"FirstName": "Mitchell",
   190  		"LastName":  "Hashimoto",
   191  		"City":      "San Francisco",
   192  	}
   193  
   194  	var result Person
   195  	err := Decode(input, &result)
   196  	if err != nil {
   197  		panic(err)
   198  	}
   199  
   200  	fmt.Printf("%s %s, %s", result.FirstName, result.LastName, result.City)
   201  	// Output:
   202  	// Mitchell Hashimoto, San Francisco
   203  }
   204  
   205  func ExampleDecode_remainingData() {
   206  	// Note that the mapstructure tags defined in the struct type
   207  	// can indicate which fields the values are mapped to.
   208  	type Person struct {
   209  		Name  string
   210  		Age   int
   211  		Other map[string]interface{} `mapstructure:",remain"`
   212  	}
   213  
   214  	input := map[string]interface{}{
   215  		"name":  "Mitchell",
   216  		"age":   91,
   217  		"email": "mitchell@example.com",
   218  	}
   219  
   220  	var result Person
   221  	err := Decode(input, &result)
   222  	if err != nil {
   223  		panic(err)
   224  	}
   225  
   226  	fmt.Printf("%#v", result)
   227  	// Output:
   228  	// mapstructure.Person{Name:"Mitchell", Age:91, Other:map[string]interface {}{"email":"mitchell@example.com"}}
   229  }
   230  
   231  func ExampleDecode_omitempty() {
   232  	// Add omitempty annotation to avoid map keys for empty values
   233  	type Family struct {
   234  		LastName string
   235  	}
   236  	type Location struct {
   237  		City string
   238  	}
   239  	type Person struct {
   240  		*Family   `mapstructure:",omitempty"`
   241  		*Location `mapstructure:",omitempty"`
   242  		Age       int
   243  		FirstName string
   244  	}
   245  
   246  	result := &map[string]interface{}{}
   247  	input := Person{FirstName: "Somebody"}
   248  	err := Decode(input, &result)
   249  	if err != nil {
   250  		panic(err)
   251  	}
   252  
   253  	fmt.Printf("%+v", result)
   254  	// Output:
   255  	// &map[Age:0 FirstName:Somebody]
   256  }
   257  

View as plain text