vendor/github.com/pelletier/go-toml/marshal.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
     4 	"bytes"
     4 	"bytes"
     5 	"errors"
     5 	"errors"
     6 	"fmt"
     6 	"fmt"
     7 	"io"
     7 	"io"
     8 	"reflect"
     8 	"reflect"
       
     9 	"sort"
     9 	"strconv"
    10 	"strconv"
    10 	"strings"
    11 	"strings"
    11 	"time"
    12 	"time"
    12 )
    13 )
    13 
    14 
    14 const tagKeyMultiline = "multiline"
    15 const (
       
    16 	tagFieldName    = "toml"
       
    17 	tagFieldComment = "comment"
       
    18 	tagCommented    = "commented"
       
    19 	tagMultiline    = "multiline"
       
    20 	tagDefault      = "default"
       
    21 )
    15 
    22 
    16 type tomlOpts struct {
    23 type tomlOpts struct {
    17 	name      string
    24 	name         string
    18 	comment   string
    25 	comment      string
    19 	commented bool
    26 	commented    bool
    20 	multiline bool
    27 	multiline    bool
    21 	include   bool
    28 	include      bool
    22 	omitempty bool
    29 	omitempty    bool
       
    30 	defaultValue string
    23 }
    31 }
    24 
    32 
    25 type encOpts struct {
    33 type encOpts struct {
    26 	quoteMapKeys            bool
    34 	quoteMapKeys            bool
    27 	arraysOneElementPerLine bool
    35 	arraysOneElementPerLine bool
    29 
    37 
    30 var encOptsDefaults = encOpts{
    38 var encOptsDefaults = encOpts{
    31 	quoteMapKeys: false,
    39 	quoteMapKeys: false,
    32 }
    40 }
    33 
    41 
       
    42 type annotation struct {
       
    43 	tag          string
       
    44 	comment      string
       
    45 	commented    string
       
    46 	multiline    string
       
    47 	defaultValue string
       
    48 }
       
    49 
       
    50 var annotationDefault = annotation{
       
    51 	tag:          tagFieldName,
       
    52 	comment:      tagFieldComment,
       
    53 	commented:    tagCommented,
       
    54 	multiline:    tagMultiline,
       
    55 	defaultValue: tagDefault,
       
    56 }
       
    57 
       
    58 type marshalOrder int
       
    59 
       
    60 // Orders the Encoder can write the fields to the output stream.
       
    61 const (
       
    62 	// Sort fields alphabetically.
       
    63 	OrderAlphabetical marshalOrder = iota + 1
       
    64 	// Preserve the order the fields are encountered. For example, the order of fields in
       
    65 	// a struct.
       
    66 	OrderPreserve
       
    67 )
       
    68 
    34 var timeType = reflect.TypeOf(time.Time{})
    69 var timeType = reflect.TypeOf(time.Time{})
    35 var marshalerType = reflect.TypeOf(new(Marshaler)).Elem()
    70 var marshalerType = reflect.TypeOf(new(Marshaler)).Elem()
    36 
    71 var localDateType = reflect.TypeOf(LocalDate{})
    37 // Check if the given marshall type maps to a Tree primitive
    72 var localTimeType = reflect.TypeOf(LocalTime{})
       
    73 var localDateTimeType = reflect.TypeOf(LocalDateTime{})
       
    74 
       
    75 // Check if the given marshal type maps to a Tree primitive
    38 func isPrimitive(mtype reflect.Type) bool {
    76 func isPrimitive(mtype reflect.Type) bool {
    39 	switch mtype.Kind() {
    77 	switch mtype.Kind() {
    40 	case reflect.Ptr:
    78 	case reflect.Ptr:
    41 		return isPrimitive(mtype.Elem())
    79 		return isPrimitive(mtype.Elem())
    42 	case reflect.Bool:
    80 	case reflect.Bool:
    48 	case reflect.Float32, reflect.Float64:
    86 	case reflect.Float32, reflect.Float64:
    49 		return true
    87 		return true
    50 	case reflect.String:
    88 	case reflect.String:
    51 		return true
    89 		return true
    52 	case reflect.Struct:
    90 	case reflect.Struct:
    53 		return mtype == timeType || isCustomMarshaler(mtype)
    91 		return mtype == timeType || mtype == localDateType || mtype == localDateTimeType || mtype == localTimeType || isCustomMarshaler(mtype)
    54 	default:
    92 	default:
    55 		return false
    93 		return false
    56 	}
    94 	}
    57 }
    95 }
    58 
    96 
    59 // Check if the given marshall type maps to a Tree slice
    97 // Check if the given marshal type maps to a Tree slice or array
    60 func isTreeSlice(mtype reflect.Type) bool {
    98 func isTreeSequence(mtype reflect.Type) bool {
    61 	switch mtype.Kind() {
    99 	switch mtype.Kind() {
    62 	case reflect.Slice:
   100 	case reflect.Ptr:
    63 		return !isOtherSlice(mtype)
   101 		return isTreeSequence(mtype.Elem())
       
   102 	case reflect.Slice, reflect.Array:
       
   103 		return isTree(mtype.Elem())
    64 	default:
   104 	default:
    65 		return false
   105 		return false
    66 	}
   106 	}
    67 }
   107 }
    68 
   108 
    69 // Check if the given marshall type maps to a non-Tree slice
   109 // Check if the given marshal type maps to a non-Tree slice or array
    70 func isOtherSlice(mtype reflect.Type) bool {
   110 func isOtherSequence(mtype reflect.Type) bool {
    71 	switch mtype.Kind() {
   111 	switch mtype.Kind() {
    72 	case reflect.Ptr:
   112 	case reflect.Ptr:
    73 		return isOtherSlice(mtype.Elem())
   113 		return isOtherSequence(mtype.Elem())
    74 	case reflect.Slice:
   114 	case reflect.Slice, reflect.Array:
    75 		return isPrimitive(mtype.Elem()) || isOtherSlice(mtype.Elem())
   115 		return !isTreeSequence(mtype)
    76 	default:
   116 	default:
    77 		return false
   117 		return false
    78 	}
   118 	}
    79 }
   119 }
    80 
   120 
    81 // Check if the given marshall type maps to a Tree
   121 // Check if the given marshal type maps to a Tree
    82 func isTree(mtype reflect.Type) bool {
   122 func isTree(mtype reflect.Type) bool {
    83 	switch mtype.Kind() {
   123 	switch mtype.Kind() {
       
   124 	case reflect.Ptr:
       
   125 		return isTree(mtype.Elem())
    84 	case reflect.Map:
   126 	case reflect.Map:
    85 		return true
   127 		return true
    86 	case reflect.Struct:
   128 	case reflect.Struct:
    87 		return !isPrimitive(mtype)
   129 		return !isPrimitive(mtype)
    88 	default:
   130 	default:
   133   uint64     uint, uint8-uint64, pointers to same
   175   uint64     uint, uint8-uint64, pointers to same
   134   int64      int, int8-uint64, pointers to same
   176   int64      int, int8-uint64, pointers to same
   135   float64    float32, float64, pointers to same
   177   float64    float32, float64, pointers to same
   136   string     string, pointers to same
   178   string     string, pointers to same
   137   bool       bool, pointers to same
   179   bool       bool, pointers to same
   138   time.Time  time.Time{}, pointers to same
   180   time.LocalTime  time.LocalTime{}, pointers to same
       
   181 
       
   182 For additional flexibility, use the Encoder API.
   139 */
   183 */
   140 func Marshal(v interface{}) ([]byte, error) {
   184 func Marshal(v interface{}) ([]byte, error) {
   141 	return NewEncoder(nil).marshal(v)
   185 	return NewEncoder(nil).marshal(v)
   142 }
   186 }
   143 
   187 
   144 // Encoder writes TOML values to an output stream.
   188 // Encoder writes TOML values to an output stream.
   145 type Encoder struct {
   189 type Encoder struct {
   146 	w io.Writer
   190 	w io.Writer
   147 	encOpts
   191 	encOpts
       
   192 	annotation
       
   193 	line  int
       
   194 	col   int
       
   195 	order marshalOrder
   148 }
   196 }
   149 
   197 
   150 // NewEncoder returns a new encoder that writes to w.
   198 // NewEncoder returns a new encoder that writes to w.
   151 func NewEncoder(w io.Writer) *Encoder {
   199 func NewEncoder(w io.Writer) *Encoder {
   152 	return &Encoder{
   200 	return &Encoder{
   153 		w:       w,
   201 		w:          w,
   154 		encOpts: encOptsDefaults,
   202 		encOpts:    encOptsDefaults,
       
   203 		annotation: annotationDefault,
       
   204 		line:       0,
       
   205 		col:        1,
       
   206 		order:      OrderAlphabetical,
   155 	}
   207 	}
   156 }
   208 }
   157 
   209 
   158 // Encode writes the TOML encoding of v to the stream.
   210 // Encode writes the TOML encoding of v to the stream.
   159 //
   211 //
   195 func (e *Encoder) ArraysWithOneElementPerLine(v bool) *Encoder {
   247 func (e *Encoder) ArraysWithOneElementPerLine(v bool) *Encoder {
   196 	e.arraysOneElementPerLine = v
   248 	e.arraysOneElementPerLine = v
   197 	return e
   249 	return e
   198 }
   250 }
   199 
   251 
       
   252 // Order allows to change in which order fields will be written to the output stream.
       
   253 func (e *Encoder) Order(ord marshalOrder) *Encoder {
       
   254 	e.order = ord
       
   255 	return e
       
   256 }
       
   257 
       
   258 // SetTagName allows changing default tag "toml"
       
   259 func (e *Encoder) SetTagName(v string) *Encoder {
       
   260 	e.tag = v
       
   261 	return e
       
   262 }
       
   263 
       
   264 // SetTagComment allows changing default tag "comment"
       
   265 func (e *Encoder) SetTagComment(v string) *Encoder {
       
   266 	e.comment = v
       
   267 	return e
       
   268 }
       
   269 
       
   270 // SetTagCommented allows changing default tag "commented"
       
   271 func (e *Encoder) SetTagCommented(v string) *Encoder {
       
   272 	e.commented = v
       
   273 	return e
       
   274 }
       
   275 
       
   276 // SetTagMultiline allows changing default tag "multiline"
       
   277 func (e *Encoder) SetTagMultiline(v string) *Encoder {
       
   278 	e.multiline = v
       
   279 	return e
       
   280 }
       
   281 
   200 func (e *Encoder) marshal(v interface{}) ([]byte, error) {
   282 func (e *Encoder) marshal(v interface{}) ([]byte, error) {
   201 	mtype := reflect.TypeOf(v)
   283 	mtype := reflect.TypeOf(v)
   202 	if mtype.Kind() != reflect.Struct {
   284 
   203 		return []byte{}, errors.New("Only a struct can be marshaled to TOML")
   285 	switch mtype.Kind() {
   204 	}
   286 	case reflect.Struct, reflect.Map:
       
   287 	case reflect.Ptr:
       
   288 		if mtype.Elem().Kind() != reflect.Struct {
       
   289 			return []byte{}, errors.New("Only pointer to struct can be marshaled to TOML")
       
   290 		}
       
   291 	default:
       
   292 		return []byte{}, errors.New("Only a struct or map can be marshaled to TOML")
       
   293 	}
       
   294 
   205 	sval := reflect.ValueOf(v)
   295 	sval := reflect.ValueOf(v)
   206 	if isCustomMarshaler(mtype) {
   296 	if isCustomMarshaler(mtype) {
   207 		return callCustomMarshaler(sval)
   297 		return callCustomMarshaler(sval)
   208 	}
   298 	}
   209 	t, err := e.valueToTree(mtype, sval)
   299 	t, err := e.valueToTree(mtype, sval)
   210 	if err != nil {
   300 	if err != nil {
   211 		return []byte{}, err
   301 		return []byte{}, err
   212 	}
   302 	}
   213 
   303 
   214 	var buf bytes.Buffer
   304 	var buf bytes.Buffer
   215 	_, err = t.writeTo(&buf, "", "", 0, e.arraysOneElementPerLine)
   305 	_, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order)
   216 
   306 
   217 	return buf.Bytes(), err
   307 	return buf.Bytes(), err
       
   308 }
       
   309 
       
   310 // Create next tree with a position based on Encoder.line
       
   311 func (e *Encoder) nextTree() *Tree {
       
   312 	return newTreeWithPosition(Position{Line: e.line, Col: 1})
   218 }
   313 }
   219 
   314 
   220 // Convert given marshal struct or map value to toml tree
   315 // Convert given marshal struct or map value to toml tree
   221 func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) {
   316 func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) {
   222 	if mtype.Kind() == reflect.Ptr {
   317 	if mtype.Kind() == reflect.Ptr {
   223 		return e.valueToTree(mtype.Elem(), mval.Elem())
   318 		return e.valueToTree(mtype.Elem(), mval.Elem())
   224 	}
   319 	}
   225 	tval := newTree()
   320 	tval := e.nextTree()
   226 	switch mtype.Kind() {
   321 	switch mtype.Kind() {
   227 	case reflect.Struct:
   322 	case reflect.Struct:
   228 		for i := 0; i < mtype.NumField(); i++ {
   323 		for i := 0; i < mtype.NumField(); i++ {
   229 			mtypef, mvalf := mtype.Field(i), mval.Field(i)
   324 			mtypef, mvalf := mtype.Field(i), mval.Field(i)
   230 			opts := tomlOptions(mtypef)
   325 			opts := tomlOptions(mtypef, e.annotation)
   231 			if opts.include && (!opts.omitempty || !isZero(mvalf)) {
   326 			if opts.include && (!opts.omitempty || !isZero(mvalf)) {
   232 				val, err := e.valueToToml(mtypef.Type, mvalf)
   327 				val, err := e.valueToToml(mtypef.Type, mvalf)
   233 				if err != nil {
   328 				if err != nil {
   234 					return nil, err
   329 					return nil, err
   235 				}
   330 				}
   240 					Multiline: opts.multiline,
   335 					Multiline: opts.multiline,
   241 				}, val)
   336 				}, val)
   242 			}
   337 			}
   243 		}
   338 		}
   244 	case reflect.Map:
   339 	case reflect.Map:
   245 		for _, key := range mval.MapKeys() {
   340 		keys := mval.MapKeys()
       
   341 		if e.order == OrderPreserve && len(keys) > 0 {
       
   342 			// Sorting []reflect.Value is not straight forward.
       
   343 			//
       
   344 			// OrderPreserve will support deterministic results when string is used
       
   345 			// as the key to maps.
       
   346 			typ := keys[0].Type()
       
   347 			kind := keys[0].Kind()
       
   348 			if kind == reflect.String {
       
   349 				ikeys := make([]string, len(keys))
       
   350 				for i := range keys {
       
   351 					ikeys[i] = keys[i].Interface().(string)
       
   352 				}
       
   353 				sort.Strings(ikeys)
       
   354 				for i := range ikeys {
       
   355 					keys[i] = reflect.ValueOf(ikeys[i]).Convert(typ)
       
   356 				}
       
   357 			}
       
   358 		}
       
   359 		for _, key := range keys {
   246 			mvalf := mval.MapIndex(key)
   360 			mvalf := mval.MapIndex(key)
   247 			val, err := e.valueToToml(mtype.Elem(), mvalf)
   361 			val, err := e.valueToToml(mtype.Elem(), mvalf)
   248 			if err != nil {
   362 			if err != nil {
   249 				return nil, err
   363 				return nil, err
   250 			}
   364 			}
   288 	return tval, nil
   402 	return tval, nil
   289 }
   403 }
   290 
   404 
   291 // Convert given marshal value to toml value
   405 // Convert given marshal value to toml value
   292 func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
   406 func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
       
   407 	e.line++
   293 	if mtype.Kind() == reflect.Ptr {
   408 	if mtype.Kind() == reflect.Ptr {
   294 		return e.valueToToml(mtype.Elem(), mval.Elem())
   409 		return e.valueToToml(mtype.Elem(), mval.Elem())
   295 	}
   410 	}
   296 	switch {
   411 	switch {
   297 	case isCustomMarshaler(mtype):
   412 	case isCustomMarshaler(mtype):
   298 		return callCustomMarshaler(mval)
   413 		return callCustomMarshaler(mval)
   299 	case isTree(mtype):
   414 	case isTree(mtype):
   300 		return e.valueToTree(mtype, mval)
   415 		return e.valueToTree(mtype, mval)
   301 	case isTreeSlice(mtype):
   416 	case isTreeSequence(mtype):
   302 		return e.valueToTreeSlice(mtype, mval)
   417 		return e.valueToTreeSlice(mtype, mval)
   303 	case isOtherSlice(mtype):
   418 	case isOtherSequence(mtype):
   304 		return e.valueToOtherSlice(mtype, mval)
   419 		return e.valueToOtherSlice(mtype, mval)
   305 	default:
   420 	default:
   306 		switch mtype.Kind() {
   421 		switch mtype.Kind() {
   307 		case reflect.Bool:
   422 		case reflect.Bool:
   308 			return mval.Bool(), nil
   423 			return mval.Bool(), nil
   309 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   424 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
       
   425 			if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) {
       
   426 				return fmt.Sprint(mval), nil
       
   427 			}
   310 			return mval.Int(), nil
   428 			return mval.Int(), nil
   311 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   429 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   312 			return mval.Uint(), nil
   430 			return mval.Uint(), nil
   313 		case reflect.Float32, reflect.Float64:
   431 		case reflect.Float32, reflect.Float64:
   314 			return mval.Float(), nil
   432 			return mval.Float(), nil
   315 		case reflect.String:
   433 		case reflect.String:
   316 			return mval.String(), nil
   434 			return mval.String(), nil
   317 		case reflect.Struct:
   435 		case reflect.Struct:
   318 			return mval.Interface().(time.Time), nil
   436 			return mval.Interface(), nil
   319 		default:
   437 		default:
   320 			return nil, fmt.Errorf("Marshal can't handle %v(%v)", mtype, mtype.Kind())
   438 			return nil, fmt.Errorf("Marshal can't handle %v(%v)", mtype, mtype.Kind())
   321 		}
   439 		}
   322 	}
   440 	}
   323 }
   441 }
   324 
   442 
   325 // Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v.
   443 // Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v.
   326 // Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for
   444 // Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for
   327 // sub-structs, and only definite types can be unmarshaled.
   445 // sub-structs, and only definite types can be unmarshaled.
   328 func (t *Tree) Unmarshal(v interface{}) error {
   446 func (t *Tree) Unmarshal(v interface{}) error {
   329 	d := Decoder{tval: t}
   447 	d := Decoder{tval: t, tagName: tagFieldName}
   330 	return d.unmarshal(v)
   448 	return d.unmarshal(v)
   331 }
   449 }
   332 
   450 
   333 // Marshal returns the TOML encoding of Tree.
   451 // Marshal returns the TOML encoding of Tree.
   334 // See Marshal() documentation for types mapping table.
   452 // See Marshal() documentation for types mapping table.
   335 func (t *Tree) Marshal() ([]byte, error) {
   453 func (t *Tree) Marshal() ([]byte, error) {
   336 	var buf bytes.Buffer
   454 	var buf bytes.Buffer
   337 	err := NewEncoder(&buf).Encode(t)
   455 	_, err := t.WriteTo(&buf)
   338 	return buf.Bytes(), err
   456 	if err != nil {
       
   457 		return nil, err
       
   458 	}
       
   459 	return buf.Bytes(), nil
   339 }
   460 }
   340 
   461 
   341 // Unmarshal parses the TOML-encoded data and stores the result in the value
   462 // Unmarshal parses the TOML-encoded data and stores the result in the value
   342 // pointed to by v. Behavior is similar to the Go json encoder, except that there
   463 // pointed to by v. Behavior is similar to the Go json encoder, except that there
   343 // is no concept of an Unmarshaler interface or UnmarshalTOML function for
   464 // is no concept of an Unmarshaler interface or UnmarshalTOML function for
   345 // `interface{}`).
   466 // `interface{}`).
   346 //
   467 //
   347 // The following struct annotations are supported:
   468 // The following struct annotations are supported:
   348 //
   469 //
   349 //   toml:"Field" Overrides the field's name to map to.
   470 //   toml:"Field" Overrides the field's name to map to.
       
   471 //   default:"foo" Provides a default value.
       
   472 //
       
   473 // For default values, only fields of the following types are supported:
       
   474 //   * string
       
   475 //   * bool
       
   476 //   * int
       
   477 //   * int64
       
   478 //   * float64
   350 //
   479 //
   351 // See Marshal() documentation for types mapping table.
   480 // See Marshal() documentation for types mapping table.
   352 func Unmarshal(data []byte, v interface{}) error {
   481 func Unmarshal(data []byte, v interface{}) error {
   353 	t, err := LoadReader(bytes.NewReader(data))
   482 	t, err := LoadReader(bytes.NewReader(data))
   354 	if err != nil {
   483 	if err != nil {
   360 // Decoder reads and decodes TOML values from an input stream.
   489 // Decoder reads and decodes TOML values from an input stream.
   361 type Decoder struct {
   490 type Decoder struct {
   362 	r    io.Reader
   491 	r    io.Reader
   363 	tval *Tree
   492 	tval *Tree
   364 	encOpts
   493 	encOpts
       
   494 	tagName string
   365 }
   495 }
   366 
   496 
   367 // NewDecoder returns a new decoder that reads from r.
   497 // NewDecoder returns a new decoder that reads from r.
   368 func NewDecoder(r io.Reader) *Decoder {
   498 func NewDecoder(r io.Reader) *Decoder {
   369 	return &Decoder{
   499 	return &Decoder{
   370 		r:       r,
   500 		r:       r,
   371 		encOpts: encOptsDefaults,
   501 		encOpts: encOptsDefaults,
       
   502 		tagName: tagFieldName,
   372 	}
   503 	}
   373 }
   504 }
   374 
   505 
   375 // Decode reads a TOML-encoded value from it's input
   506 // Decode reads a TOML-encoded value from it's input
   376 // and unmarshals it in the value pointed at by v.
   507 // and unmarshals it in the value pointed at by v.
   383 		return err
   514 		return err
   384 	}
   515 	}
   385 	return d.unmarshal(v)
   516 	return d.unmarshal(v)
   386 }
   517 }
   387 
   518 
       
   519 // SetTagName allows changing default tag "toml"
       
   520 func (d *Decoder) SetTagName(v string) *Decoder {
       
   521 	d.tagName = v
       
   522 	return d
       
   523 }
       
   524 
   388 func (d *Decoder) unmarshal(v interface{}) error {
   525 func (d *Decoder) unmarshal(v interface{}) error {
   389 	mtype := reflect.TypeOf(v)
   526 	mtype := reflect.TypeOf(v)
   390 	if mtype.Kind() != reflect.Ptr || mtype.Elem().Kind() != reflect.Struct {
   527 	if mtype.Kind() != reflect.Ptr {
   391 		return errors.New("Only a pointer to struct can be unmarshaled from TOML")
   528 		return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
   392 	}
   529 	}
   393 
   530 
   394 	sval, err := d.valueFromTree(mtype.Elem(), d.tval)
   531 	elem := mtype.Elem()
       
   532 
       
   533 	switch elem.Kind() {
       
   534 	case reflect.Struct, reflect.Map:
       
   535 	default:
       
   536 		return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
       
   537 	}
       
   538 
       
   539 	vv := reflect.ValueOf(v).Elem()
       
   540 
       
   541 	sval, err := d.valueFromTree(elem, d.tval, &vv)
   395 	if err != nil {
   542 	if err != nil {
   396 		return err
   543 		return err
   397 	}
   544 	}
   398 	reflect.ValueOf(v).Elem().Set(sval)
   545 	reflect.ValueOf(v).Elem().Set(sval)
   399 	return nil
   546 	return nil
   400 }
   547 }
   401 
   548 
   402 // Convert toml tree to marshal struct or map, using marshal type
   549 // Convert toml tree to marshal struct or map, using marshal type. When mval1
   403 func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) {
   550 // is non-nil, merge fields into the given value instead of allocating a new one.
       
   551 func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree, mval1 *reflect.Value) (reflect.Value, error) {
   404 	if mtype.Kind() == reflect.Ptr {
   552 	if mtype.Kind() == reflect.Ptr {
   405 		return d.unwrapPointer(mtype, tval)
   553 		return d.unwrapPointer(mtype, tval, mval1)
   406 	}
   554 	}
   407 	var mval reflect.Value
   555 	var mval reflect.Value
   408 	switch mtype.Kind() {
   556 	switch mtype.Kind() {
   409 	case reflect.Struct:
   557 	case reflect.Struct:
   410 		mval = reflect.New(mtype).Elem()
   558 		if mval1 != nil {
       
   559 			mval = *mval1
       
   560 		} else {
       
   561 			mval = reflect.New(mtype).Elem()
       
   562 		}
       
   563 
   411 		for i := 0; i < mtype.NumField(); i++ {
   564 		for i := 0; i < mtype.NumField(); i++ {
   412 			mtypef := mtype.Field(i)
   565 			mtypef := mtype.Field(i)
   413 			opts := tomlOptions(mtypef)
   566 			an := annotation{tag: d.tagName}
       
   567 			opts := tomlOptions(mtypef, an)
   414 			if opts.include {
   568 			if opts.include {
   415 				baseKey := opts.name
   569 				baseKey := opts.name
   416 				keysToTry := []string{baseKey, strings.ToLower(baseKey), strings.ToTitle(baseKey)}
   570 				keysToTry := []string{
       
   571 					baseKey,
       
   572 					strings.ToLower(baseKey),
       
   573 					strings.ToTitle(baseKey),
       
   574 					strings.ToLower(string(baseKey[0])) + baseKey[1:],
       
   575 				}
       
   576 
       
   577 				found := false
   417 				for _, key := range keysToTry {
   578 				for _, key := range keysToTry {
   418 					exists := tval.Has(key)
   579 					exists := tval.Has(key)
   419 					if !exists {
   580 					if !exists {
   420 						continue
   581 						continue
   421 					}
   582 					}
   422 					val := tval.Get(key)
   583 					val := tval.Get(key)
   423 					mvalf, err := d.valueFromToml(mtypef.Type, val)
   584 					fval := mval.Field(i)
       
   585 					mvalf, err := d.valueFromToml(mtypef.Type, val, &fval)
   424 					if err != nil {
   586 					if err != nil {
   425 						return mval, formatError(err, tval.GetPosition(key))
   587 						return mval, formatError(err, tval.GetPosition(key))
   426 					}
   588 					}
   427 					mval.Field(i).Set(mvalf)
   589 					mval.Field(i).Set(mvalf)
       
   590 					found = true
   428 					break
   591 					break
       
   592 				}
       
   593 
       
   594 				if !found && opts.defaultValue != "" {
       
   595 					mvalf := mval.Field(i)
       
   596 					var val interface{}
       
   597 					var err error
       
   598 					switch mvalf.Kind() {
       
   599 					case reflect.Bool:
       
   600 						val, err = strconv.ParseBool(opts.defaultValue)
       
   601 						if err != nil {
       
   602 							return mval.Field(i), err
       
   603 						}
       
   604 					case reflect.Int:
       
   605 						val, err = strconv.Atoi(opts.defaultValue)
       
   606 						if err != nil {
       
   607 							return mval.Field(i), err
       
   608 						}
       
   609 					case reflect.String:
       
   610 						val = opts.defaultValue
       
   611 					case reflect.Int64:
       
   612 						val, err = strconv.ParseInt(opts.defaultValue, 10, 64)
       
   613 						if err != nil {
       
   614 							return mval.Field(i), err
       
   615 						}
       
   616 					case reflect.Float64:
       
   617 						val, err = strconv.ParseFloat(opts.defaultValue, 64)
       
   618 						if err != nil {
       
   619 							return mval.Field(i), err
       
   620 						}
       
   621 					default:
       
   622 						return mval.Field(i), fmt.Errorf("unsuported field type for default option")
       
   623 					}
       
   624 					mval.Field(i).Set(reflect.ValueOf(val))
       
   625 				}
       
   626 
       
   627 				// save the old behavior above and try to check anonymous structs
       
   628 				if !found && opts.defaultValue == "" && mtypef.Anonymous && mtypef.Type.Kind() == reflect.Struct {
       
   629 					v, err := d.valueFromTree(mtypef.Type, tval, nil)
       
   630 					if err != nil {
       
   631 						return v, err
       
   632 					}
       
   633 					mval.Field(i).Set(v)
   429 				}
   634 				}
   430 			}
   635 			}
   431 		}
   636 		}
   432 	case reflect.Map:
   637 	case reflect.Map:
   433 		mval = reflect.MakeMap(mtype)
   638 		mval = reflect.MakeMap(mtype)
   434 		for _, key := range tval.Keys() {
   639 		for _, key := range tval.Keys() {
   435 			// TODO: path splits key
   640 			// TODO: path splits key
   436 			val := tval.GetPath([]string{key})
   641 			val := tval.GetPath([]string{key})
   437 			mvalf, err := d.valueFromToml(mtype.Elem(), val)
   642 			mvalf, err := d.valueFromToml(mtype.Elem(), val, nil)
   438 			if err != nil {
   643 			if err != nil {
   439 				return mval, formatError(err, tval.GetPosition(key))
   644 				return mval, formatError(err, tval.GetPosition(key))
   440 			}
   645 			}
   441 			mval.SetMapIndex(reflect.ValueOf(key), mvalf)
   646 			mval.SetMapIndex(reflect.ValueOf(key).Convert(mtype.Key()), mvalf)
   442 		}
   647 		}
   443 	}
   648 	}
   444 	return mval, nil
   649 	return mval, nil
   445 }
   650 }
   446 
   651 
   447 // Convert toml value to marshal struct/map slice, using marshal type
   652 // Convert toml value to marshal struct/map slice, using marshal type
   448 func (d *Decoder) valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) {
   653 func (d *Decoder) valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) {
   449 	mval := reflect.MakeSlice(mtype, len(tval), len(tval))
   654 	mval := reflect.MakeSlice(mtype, len(tval), len(tval))
   450 	for i := 0; i < len(tval); i++ {
   655 	for i := 0; i < len(tval); i++ {
   451 		val, err := d.valueFromTree(mtype.Elem(), tval[i])
   656 		val, err := d.valueFromTree(mtype.Elem(), tval[i], nil)
   452 		if err != nil {
   657 		if err != nil {
   453 			return mval, err
   658 			return mval, err
   454 		}
   659 		}
   455 		mval.Index(i).Set(val)
   660 		mval.Index(i).Set(val)
   456 	}
   661 	}
   459 
   664 
   460 // Convert toml value to marshal primitive slice, using marshal type
   665 // Convert toml value to marshal primitive slice, using marshal type
   461 func (d *Decoder) valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value, error) {
   666 func (d *Decoder) valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value, error) {
   462 	mval := reflect.MakeSlice(mtype, len(tval), len(tval))
   667 	mval := reflect.MakeSlice(mtype, len(tval), len(tval))
   463 	for i := 0; i < len(tval); i++ {
   668 	for i := 0; i < len(tval); i++ {
   464 		val, err := d.valueFromToml(mtype.Elem(), tval[i])
   669 		val, err := d.valueFromToml(mtype.Elem(), tval[i], nil)
   465 		if err != nil {
   670 		if err != nil {
   466 			return mval, err
   671 			return mval, err
   467 		}
   672 		}
   468 		mval.Index(i).Set(val)
   673 		mval.Index(i).Set(val)
   469 	}
   674 	}
   470 	return mval, nil
   675 	return mval, nil
   471 }
   676 }
   472 
   677 
   473 // Convert toml value to marshal value, using marshal type
   678 // Convert toml value to marshal value, using marshal type. When mval1 is non-nil
   474 func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}) (reflect.Value, error) {
   679 // and the given type is a struct value, merge fields into it.
       
   680 func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *reflect.Value) (reflect.Value, error) {
   475 	if mtype.Kind() == reflect.Ptr {
   681 	if mtype.Kind() == reflect.Ptr {
   476 		return d.unwrapPointer(mtype, tval)
   682 		return d.unwrapPointer(mtype, tval, mval1)
   477 	}
   683 	}
   478 
   684 
   479 	switch tval.(type) {
   685 	switch t := tval.(type) {
   480 	case *Tree:
   686 	case *Tree:
       
   687 		var mval11 *reflect.Value
       
   688 		if mtype.Kind() == reflect.Struct {
       
   689 			mval11 = mval1
       
   690 		}
       
   691 
   481 		if isTree(mtype) {
   692 		if isTree(mtype) {
   482 			return d.valueFromTree(mtype, tval.(*Tree))
   693 			return d.valueFromTree(mtype, t, mval11)
   483 		}
   694 		}
   484 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
   695 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
   485 	case []*Tree:
   696 	case []*Tree:
   486 		if isTreeSlice(mtype) {
   697 		if isTreeSequence(mtype) {
   487 			return d.valueFromTreeSlice(mtype, tval.([]*Tree))
   698 			return d.valueFromTreeSlice(mtype, t)
   488 		}
   699 		}
   489 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
   700 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
   490 	case []interface{}:
   701 	case []interface{}:
   491 		if isOtherSlice(mtype) {
   702 		if isOtherSequence(mtype) {
   492 			return d.valueFromOtherSlice(mtype, tval.([]interface{}))
   703 			return d.valueFromOtherSlice(mtype, t)
   493 		}
   704 		}
   494 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
   705 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
   495 	default:
   706 	default:
   496 		switch mtype.Kind() {
   707 		switch mtype.Kind() {
   497 		case reflect.Bool, reflect.Struct:
   708 		case reflect.Bool, reflect.Struct:
   498 			val := reflect.ValueOf(tval)
   709 			val := reflect.ValueOf(tval)
   499 			// if this passes for when mtype is reflect.Struct, tval is a time.Time
   710 
       
   711 			switch val.Type() {
       
   712 			case localDateType:
       
   713 				localDate := val.Interface().(LocalDate)
       
   714 				switch mtype {
       
   715 				case timeType:
       
   716 					return reflect.ValueOf(time.Date(localDate.Year, localDate.Month, localDate.Day, 0, 0, 0, 0, time.Local)), nil
       
   717 				}
       
   718 			case localDateTimeType:
       
   719 				localDateTime := val.Interface().(LocalDateTime)
       
   720 				switch mtype {
       
   721 				case timeType:
       
   722 					return reflect.ValueOf(time.Date(
       
   723 						localDateTime.Date.Year,
       
   724 						localDateTime.Date.Month,
       
   725 						localDateTime.Date.Day,
       
   726 						localDateTime.Time.Hour,
       
   727 						localDateTime.Time.Minute,
       
   728 						localDateTime.Time.Second,
       
   729 						localDateTime.Time.Nanosecond,
       
   730 						time.Local)), nil
       
   731 				}
       
   732 			}
       
   733 
       
   734 			// if this passes for when mtype is reflect.Struct, tval is a time.LocalTime
   500 			if !val.Type().ConvertibleTo(mtype) {
   735 			if !val.Type().ConvertibleTo(mtype) {
   501 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   736 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   502 			}
   737 			}
   503 
   738 
   504 			return val.Convert(mtype), nil
   739 			return val.Convert(mtype), nil
   510 			}
   745 			}
   511 
   746 
   512 			return val.Convert(mtype), nil
   747 			return val.Convert(mtype), nil
   513 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   748 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   514 			val := reflect.ValueOf(tval)
   749 			val := reflect.ValueOf(tval)
       
   750 			if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) && val.Kind() == reflect.String {
       
   751 				d, err := time.ParseDuration(val.String())
       
   752 				if err != nil {
       
   753 					return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v. %s", tval, tval, mtype.String(), err)
       
   754 				}
       
   755 				return reflect.ValueOf(d), nil
       
   756 			}
   515 			if !val.Type().ConvertibleTo(mtype) {
   757 			if !val.Type().ConvertibleTo(mtype) {
   516 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   758 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   517 			}
   759 			}
   518 			if reflect.Indirect(reflect.New(mtype)).OverflowInt(val.Int()) {
   760 			if reflect.Indirect(reflect.New(mtype)).OverflowInt(val.Convert(mtype).Int()) {
   519 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
   761 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
   520 			}
   762 			}
   521 
   763 
   522 			return val.Convert(mtype), nil
   764 			return val.Convert(mtype), nil
   523 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   765 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   524 			val := reflect.ValueOf(tval)
   766 			val := reflect.ValueOf(tval)
   525 			if !val.Type().ConvertibleTo(mtype) {
   767 			if !val.Type().ConvertibleTo(mtype) {
   526 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   768 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   527 			}
   769 			}
   528 			if val.Int() < 0 {
   770 
       
   771 			if val.Convert(reflect.TypeOf(int(1))).Int() < 0 {
   529 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String())
   772 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String())
   530 			}
   773 			}
   531 			if reflect.Indirect(reflect.New(mtype)).OverflowUint(uint64(val.Int())) {
   774 			if reflect.Indirect(reflect.New(mtype)).OverflowUint(uint64(val.Convert(mtype).Uint())) {
   532 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
   775 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
   533 			}
   776 			}
   534 
   777 
   535 			return val.Convert(mtype), nil
   778 			return val.Convert(mtype), nil
   536 		case reflect.Float32, reflect.Float64:
   779 		case reflect.Float32, reflect.Float64:
   537 			val := reflect.ValueOf(tval)
   780 			val := reflect.ValueOf(tval)
   538 			if !val.Type().ConvertibleTo(mtype) {
   781 			if !val.Type().ConvertibleTo(mtype) {
   539 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   782 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   540 			}
   783 			}
   541 			if reflect.Indirect(reflect.New(mtype)).OverflowFloat(val.Float()) {
   784 			if reflect.Indirect(reflect.New(mtype)).OverflowFloat(val.Convert(mtype).Float()) {
   542 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
   785 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
   543 			}
   786 			}
   544 
   787 
   545 			return val.Convert(mtype), nil
   788 			return val.Convert(mtype), nil
   546 		default:
   789 		default:
   547 			return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind())
   790 			return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind())
   548 		}
   791 		}
   549 	}
   792 	}
   550 }
   793 }
   551 
   794 
   552 func (d *Decoder) unwrapPointer(mtype reflect.Type, tval interface{}) (reflect.Value, error) {
   795 func (d *Decoder) unwrapPointer(mtype reflect.Type, tval interface{}, mval1 *reflect.Value) (reflect.Value, error) {
   553 	val, err := d.valueFromToml(mtype.Elem(), tval)
   796 	var melem *reflect.Value
       
   797 
       
   798 	if mval1 != nil && !mval1.IsNil() && mtype.Elem().Kind() == reflect.Struct {
       
   799 		elem := mval1.Elem()
       
   800 		melem = &elem
       
   801 	}
       
   802 
       
   803 	val, err := d.valueFromToml(mtype.Elem(), tval, melem)
   554 	if err != nil {
   804 	if err != nil {
   555 		return reflect.ValueOf(nil), err
   805 		return reflect.ValueOf(nil), err
   556 	}
   806 	}
   557 	mval := reflect.New(mtype.Elem())
   807 	mval := reflect.New(mtype.Elem())
   558 	mval.Elem().Set(val)
   808 	mval.Elem().Set(val)
   559 	return mval, nil
   809 	return mval, nil
   560 }
   810 }
   561 
   811 
   562 func tomlOptions(vf reflect.StructField) tomlOpts {
   812 func tomlOptions(vf reflect.StructField, an annotation) tomlOpts {
   563 	tag := vf.Tag.Get("toml")
   813 	tag := vf.Tag.Get(an.tag)
   564 	parse := strings.Split(tag, ",")
   814 	parse := strings.Split(tag, ",")
   565 	var comment string
   815 	var comment string
   566 	if c := vf.Tag.Get("comment"); c != "" {
   816 	if c := vf.Tag.Get(an.comment); c != "" {
   567 		comment = c
   817 		comment = c
   568 	}
   818 	}
   569 	commented, _ := strconv.ParseBool(vf.Tag.Get("commented"))
   819 	commented, _ := strconv.ParseBool(vf.Tag.Get(an.commented))
   570 	multiline, _ := strconv.ParseBool(vf.Tag.Get(tagKeyMultiline))
   820 	multiline, _ := strconv.ParseBool(vf.Tag.Get(an.multiline))
   571 	result := tomlOpts{name: vf.Name, comment: comment, commented: commented, multiline: multiline, include: true, omitempty: false}
   821 	defaultValue := vf.Tag.Get(tagDefault)
       
   822 	result := tomlOpts{
       
   823 		name:         vf.Name,
       
   824 		comment:      comment,
       
   825 		commented:    commented,
       
   826 		multiline:    multiline,
       
   827 		include:      true,
       
   828 		omitempty:    false,
       
   829 		defaultValue: defaultValue,
       
   830 	}
   572 	if parse[0] != "" {
   831 	if parse[0] != "" {
   573 		if parse[0] == "-" && len(parse) == 1 {
   832 		if parse[0] == "-" && len(parse) == 1 {
   574 			result.include = false
   833 			result.include = false
   575 		} else {
   834 		} else {
   576 			result.name = strings.Trim(parse[0], " ")
   835 			result.name = strings.Trim(parse[0], " ")