vendor/github.com/pelletier/go-toml/marshal.go
changeset 256 6d9efbef00a9
parent 251 1c52a0eeb952
child 260 445e01aede7e
equal deleted inserted replaced
255:4f153a23adab 256:6d9efbef00a9
     1 package toml
     1 package toml
     2 
     2 
     3 import (
     3 import (
     4 	"bytes"
     4 	"bytes"
       
     5 	"encoding"
     5 	"errors"
     6 	"errors"
     6 	"fmt"
     7 	"fmt"
     7 	"io"
     8 	"io"
     8 	"reflect"
     9 	"reflect"
     9 	"sort"
    10 	"sort"
    15 const (
    16 const (
    16 	tagFieldName    = "toml"
    17 	tagFieldName    = "toml"
    17 	tagFieldComment = "comment"
    18 	tagFieldComment = "comment"
    18 	tagCommented    = "commented"
    19 	tagCommented    = "commented"
    19 	tagMultiline    = "multiline"
    20 	tagMultiline    = "multiline"
       
    21 	tagLiteral      = "literal"
    20 	tagDefault      = "default"
    22 	tagDefault      = "default"
    21 )
    23 )
    22 
    24 
    23 type tomlOpts struct {
    25 type tomlOpts struct {
    24 	name         string
    26 	name         string
       
    27 	nameFromTag  bool
    25 	comment      string
    28 	comment      string
    26 	commented    bool
    29 	commented    bool
    27 	multiline    bool
    30 	multiline    bool
       
    31 	literal      bool
    28 	include      bool
    32 	include      bool
    29 	omitempty    bool
    33 	omitempty    bool
    30 	defaultValue string
    34 	defaultValue string
    31 }
    35 }
    32 
    36 
    42 type annotation struct {
    46 type annotation struct {
    43 	tag          string
    47 	tag          string
    44 	comment      string
    48 	comment      string
    45 	commented    string
    49 	commented    string
    46 	multiline    string
    50 	multiline    string
       
    51 	literal      string
    47 	defaultValue string
    52 	defaultValue string
    48 }
    53 }
    49 
    54 
    50 var annotationDefault = annotation{
    55 var annotationDefault = annotation{
    51 	tag:          tagFieldName,
    56 	tag:          tagFieldName,
    52 	comment:      tagFieldComment,
    57 	comment:      tagFieldComment,
    53 	commented:    tagCommented,
    58 	commented:    tagCommented,
    54 	multiline:    tagMultiline,
    59 	multiline:    tagMultiline,
       
    60 	literal:      tagLiteral,
    55 	defaultValue: tagDefault,
    61 	defaultValue: tagDefault,
    56 }
    62 }
    57 
    63 
    58 type marshalOrder int
    64 type MarshalOrder int
    59 
    65 
    60 // Orders the Encoder can write the fields to the output stream.
    66 // Orders the Encoder can write the fields to the output stream.
    61 const (
    67 const (
    62 	// Sort fields alphabetically.
    68 	// Sort fields alphabetically.
    63 	OrderAlphabetical marshalOrder = iota + 1
    69 	OrderAlphabetical MarshalOrder = iota + 1
    64 	// Preserve the order the fields are encountered. For example, the order of fields in
    70 	// Preserve the order the fields are encountered. For example, the order of fields in
    65 	// a struct.
    71 	// a struct.
    66 	OrderPreserve
    72 	OrderPreserve
    67 )
    73 )
    68 
    74 
    69 var timeType = reflect.TypeOf(time.Time{})
    75 var timeType = reflect.TypeOf(time.Time{})
    70 var marshalerType = reflect.TypeOf(new(Marshaler)).Elem()
    76 var marshalerType = reflect.TypeOf(new(Marshaler)).Elem()
       
    77 var unmarshalerType = reflect.TypeOf(new(Unmarshaler)).Elem()
       
    78 var textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()
       
    79 var textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
    71 var localDateType = reflect.TypeOf(LocalDate{})
    80 var localDateType = reflect.TypeOf(LocalDate{})
    72 var localTimeType = reflect.TypeOf(LocalTime{})
    81 var localTimeType = reflect.TypeOf(LocalTime{})
    73 var localDateTimeType = reflect.TypeOf(LocalDateTime{})
    82 var localDateTimeType = reflect.TypeOf(LocalDateTime{})
       
    83 var mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{})
    74 
    84 
    75 // Check if the given marshal type maps to a Tree primitive
    85 // Check if the given marshal type maps to a Tree primitive
    76 func isPrimitive(mtype reflect.Type) bool {
    86 func isPrimitive(mtype reflect.Type) bool {
    77 	switch mtype.Kind() {
    87 	switch mtype.Kind() {
    78 	case reflect.Ptr:
    88 	case reflect.Ptr:
    86 	case reflect.Float32, reflect.Float64:
    96 	case reflect.Float32, reflect.Float64:
    87 		return true
    97 		return true
    88 	case reflect.String:
    98 	case reflect.String:
    89 		return true
    99 		return true
    90 	case reflect.Struct:
   100 	case reflect.Struct:
    91 		return mtype == timeType || mtype == localDateType || mtype == localDateTimeType || mtype == localTimeType || isCustomMarshaler(mtype)
   101 		return isTimeType(mtype)
    92 	default:
   102 	default:
    93 		return false
   103 		return false
    94 	}
   104 	}
       
   105 }
       
   106 
       
   107 func isTimeType(mtype reflect.Type) bool {
       
   108 	return mtype == timeType || mtype == localDateType || mtype == localDateTimeType || mtype == localTimeType
    95 }
   109 }
    96 
   110 
    97 // Check if the given marshal type maps to a Tree slice or array
   111 // Check if the given marshal type maps to a Tree slice or array
    98 func isTreeSequence(mtype reflect.Type) bool {
   112 func isTreeSequence(mtype reflect.Type) bool {
    99 	switch mtype.Kind() {
   113 	switch mtype.Kind() {
   100 	case reflect.Ptr:
   114 	case reflect.Ptr:
   101 		return isTreeSequence(mtype.Elem())
   115 		return isTreeSequence(mtype.Elem())
   102 	case reflect.Slice, reflect.Array:
   116 	case reflect.Slice, reflect.Array:
   103 		return isTree(mtype.Elem())
   117 		return isTree(mtype.Elem())
       
   118 	default:
       
   119 		return false
       
   120 	}
       
   121 }
       
   122 
       
   123 // Check if the given marshal type maps to a slice or array of a custom marshaler type
       
   124 func isCustomMarshalerSequence(mtype reflect.Type) bool {
       
   125 	switch mtype.Kind() {
       
   126 	case reflect.Ptr:
       
   127 		return isCustomMarshalerSequence(mtype.Elem())
       
   128 	case reflect.Slice, reflect.Array:
       
   129 		return isCustomMarshaler(mtype.Elem()) || isCustomMarshaler(reflect.New(mtype.Elem()).Type())
       
   130 	default:
       
   131 		return false
       
   132 	}
       
   133 }
       
   134 
       
   135 // Check if the given marshal type maps to a slice or array of a text marshaler type
       
   136 func isTextMarshalerSequence(mtype reflect.Type) bool {
       
   137 	switch mtype.Kind() {
       
   138 	case reflect.Ptr:
       
   139 		return isTextMarshalerSequence(mtype.Elem())
       
   140 	case reflect.Slice, reflect.Array:
       
   141 		return isTextMarshaler(mtype.Elem()) || isTextMarshaler(reflect.New(mtype.Elem()).Type())
   104 	default:
   142 	default:
   105 		return false
   143 		return false
   106 	}
   144 	}
   107 }
   145 }
   108 
   146 
   138 
   176 
   139 func callCustomMarshaler(mval reflect.Value) ([]byte, error) {
   177 func callCustomMarshaler(mval reflect.Value) ([]byte, error) {
   140 	return mval.Interface().(Marshaler).MarshalTOML()
   178 	return mval.Interface().(Marshaler).MarshalTOML()
   141 }
   179 }
   142 
   180 
       
   181 func isTextMarshaler(mtype reflect.Type) bool {
       
   182 	return mtype.Implements(textMarshalerType) && !isTimeType(mtype)
       
   183 }
       
   184 
       
   185 func callTextMarshaler(mval reflect.Value) ([]byte, error) {
       
   186 	return mval.Interface().(encoding.TextMarshaler).MarshalText()
       
   187 }
       
   188 
       
   189 func isCustomUnmarshaler(mtype reflect.Type) bool {
       
   190 	return mtype.Implements(unmarshalerType)
       
   191 }
       
   192 
       
   193 func callCustomUnmarshaler(mval reflect.Value, tval interface{}) error {
       
   194 	return mval.Interface().(Unmarshaler).UnmarshalTOML(tval)
       
   195 }
       
   196 
       
   197 func isTextUnmarshaler(mtype reflect.Type) bool {
       
   198 	return mtype.Implements(textUnmarshalerType)
       
   199 }
       
   200 
       
   201 func callTextUnmarshaler(mval reflect.Value, text []byte) error {
       
   202 	return mval.Interface().(encoding.TextUnmarshaler).UnmarshalText(text)
       
   203 }
       
   204 
   143 // Marshaler is the interface implemented by types that
   205 // Marshaler is the interface implemented by types that
   144 // can marshal themselves into valid TOML.
   206 // can marshal themselves into valid TOML.
   145 type Marshaler interface {
   207 type Marshaler interface {
   146 	MarshalTOML() ([]byte, error)
   208 	MarshalTOML() ([]byte, error)
       
   209 }
       
   210 
       
   211 // Unmarshaler is the interface implemented by types that
       
   212 // can unmarshal a TOML description of themselves.
       
   213 type Unmarshaler interface {
       
   214 	UnmarshalTOML(interface{}) error
   147 }
   215 }
   148 
   216 
   149 /*
   217 /*
   150 Marshal returns the TOML encoding of v.  Behavior is similar to the Go json
   218 Marshal returns the TOML encoding of v.  Behavior is similar to the Go json
   151 encoder, except that there is no concept of a Marshaler interface or MarshalTOML
   219 encoder, except that there is no concept of a Marshaler interface or MarshalTOML
   188 // Encoder writes TOML values to an output stream.
   256 // Encoder writes TOML values to an output stream.
   189 type Encoder struct {
   257 type Encoder struct {
   190 	w io.Writer
   258 	w io.Writer
   191 	encOpts
   259 	encOpts
   192 	annotation
   260 	annotation
   193 	line  int
   261 	line            int
   194 	col   int
   262 	col             int
   195 	order marshalOrder
   263 	order           MarshalOrder
       
   264 	promoteAnon     bool
       
   265 	compactComments bool
       
   266 	indentation     string
   196 }
   267 }
   197 
   268 
   198 // NewEncoder returns a new encoder that writes to w.
   269 // NewEncoder returns a new encoder that writes to w.
   199 func NewEncoder(w io.Writer) *Encoder {
   270 func NewEncoder(w io.Writer) *Encoder {
   200 	return &Encoder{
   271 	return &Encoder{
   201 		w:          w,
   272 		w:           w,
   202 		encOpts:    encOptsDefaults,
   273 		encOpts:     encOptsDefaults,
   203 		annotation: annotationDefault,
   274 		annotation:  annotationDefault,
   204 		line:       0,
   275 		line:        0,
   205 		col:        1,
   276 		col:         1,
   206 		order:      OrderAlphabetical,
   277 		order:       OrderAlphabetical,
       
   278 		indentation: "  ",
   207 	}
   279 	}
   208 }
   280 }
   209 
   281 
   210 // Encode writes the TOML encoding of v to the stream.
   282 // Encode writes the TOML encoding of v to the stream.
   211 //
   283 //
   248 	e.arraysOneElementPerLine = v
   320 	e.arraysOneElementPerLine = v
   249 	return e
   321 	return e
   250 }
   322 }
   251 
   323 
   252 // Order allows to change in which order fields will be written to the output stream.
   324 // Order allows to change in which order fields will be written to the output stream.
   253 func (e *Encoder) Order(ord marshalOrder) *Encoder {
   325 func (e *Encoder) Order(ord MarshalOrder) *Encoder {
   254 	e.order = ord
   326 	e.order = ord
       
   327 	return e
       
   328 }
       
   329 
       
   330 // Indentation allows to change indentation when marshalling.
       
   331 func (e *Encoder) Indentation(indent string) *Encoder {
       
   332 	e.indentation = indent
   255 	return e
   333 	return e
   256 }
   334 }
   257 
   335 
   258 // SetTagName allows changing default tag "toml"
   336 // SetTagName allows changing default tag "toml"
   259 func (e *Encoder) SetTagName(v string) *Encoder {
   337 func (e *Encoder) SetTagName(v string) *Encoder {
   277 func (e *Encoder) SetTagMultiline(v string) *Encoder {
   355 func (e *Encoder) SetTagMultiline(v string) *Encoder {
   278 	e.multiline = v
   356 	e.multiline = v
   279 	return e
   357 	return e
   280 }
   358 }
   281 
   359 
       
   360 // PromoteAnonymous allows to change how anonymous struct fields are marshaled.
       
   361 // Usually, they are marshaled as if the inner exported fields were fields in
       
   362 // the outer struct. However, if an anonymous struct field is given a name in
       
   363 // its TOML tag, it is treated like a regular struct field with that name.
       
   364 // rather than being anonymous.
       
   365 //
       
   366 // In case anonymous promotion is enabled, all anonymous structs are promoted
       
   367 // and treated like regular struct fields.
       
   368 func (e *Encoder) PromoteAnonymous(promote bool) *Encoder {
       
   369 	e.promoteAnon = promote
       
   370 	return e
       
   371 }
       
   372 
       
   373 // CompactComments removes the new line before each comment in the tree.
       
   374 func (e *Encoder) CompactComments(cc bool) *Encoder {
       
   375 	e.compactComments = cc
       
   376 	return e
       
   377 }
       
   378 
   282 func (e *Encoder) marshal(v interface{}) ([]byte, error) {
   379 func (e *Encoder) marshal(v interface{}) ([]byte, error) {
       
   380 	// Check if indentation is valid
       
   381 	for _, char := range e.indentation {
       
   382 		if !isSpace(char) {
       
   383 			return []byte{}, fmt.Errorf("invalid indentation: must only contains space or tab characters")
       
   384 		}
       
   385 	}
       
   386 
   283 	mtype := reflect.TypeOf(v)
   387 	mtype := reflect.TypeOf(v)
       
   388 	if mtype == nil {
       
   389 		return []byte{}, errors.New("nil cannot be marshaled to TOML")
       
   390 	}
   284 
   391 
   285 	switch mtype.Kind() {
   392 	switch mtype.Kind() {
   286 	case reflect.Struct, reflect.Map:
   393 	case reflect.Struct, reflect.Map:
   287 	case reflect.Ptr:
   394 	case reflect.Ptr:
   288 		if mtype.Elem().Kind() != reflect.Struct {
   395 		if mtype.Elem().Kind() != reflect.Struct {
   289 			return []byte{}, errors.New("Only pointer to struct can be marshaled to TOML")
   396 			return []byte{}, errors.New("Only pointer to struct can be marshaled to TOML")
   290 		}
   397 		}
       
   398 		if reflect.ValueOf(v).IsNil() {
       
   399 			return []byte{}, errors.New("nil pointer cannot be marshaled to TOML")
       
   400 		}
   291 	default:
   401 	default:
   292 		return []byte{}, errors.New("Only a struct or map can be marshaled to TOML")
   402 		return []byte{}, errors.New("Only a struct or map can be marshaled to TOML")
   293 	}
   403 	}
   294 
   404 
   295 	sval := reflect.ValueOf(v)
   405 	sval := reflect.ValueOf(v)
   296 	if isCustomMarshaler(mtype) {
   406 	if isCustomMarshaler(mtype) {
   297 		return callCustomMarshaler(sval)
   407 		return callCustomMarshaler(sval)
   298 	}
   408 	}
       
   409 	if isTextMarshaler(mtype) {
       
   410 		return callTextMarshaler(sval)
       
   411 	}
   299 	t, err := e.valueToTree(mtype, sval)
   412 	t, err := e.valueToTree(mtype, sval)
   300 	if err != nil {
   413 	if err != nil {
   301 		return []byte{}, err
   414 		return []byte{}, err
   302 	}
   415 	}
   303 
   416 
   304 	var buf bytes.Buffer
   417 	var buf bytes.Buffer
   305 	_, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order)
   418 	_, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order, e.indentation, e.compactComments, false)
   306 
   419 
   307 	return buf.Bytes(), err
   420 	return buf.Bytes(), err
   308 }
   421 }
   309 
   422 
   310 // Create next tree with a position based on Encoder.line
   423 // Create next tree with a position based on Encoder.line
   318 		return e.valueToTree(mtype.Elem(), mval.Elem())
   431 		return e.valueToTree(mtype.Elem(), mval.Elem())
   319 	}
   432 	}
   320 	tval := e.nextTree()
   433 	tval := e.nextTree()
   321 	switch mtype.Kind() {
   434 	switch mtype.Kind() {
   322 	case reflect.Struct:
   435 	case reflect.Struct:
   323 		for i := 0; i < mtype.NumField(); i++ {
   436 		switch mval.Interface().(type) {
   324 			mtypef, mvalf := mtype.Field(i), mval.Field(i)
   437 		case Tree:
   325 			opts := tomlOptions(mtypef, e.annotation)
   438 			reflect.ValueOf(tval).Elem().Set(mval)
   326 			if opts.include && (!opts.omitempty || !isZero(mvalf)) {
   439 		default:
   327 				val, err := e.valueToToml(mtypef.Type, mvalf)
   440 			for i := 0; i < mtype.NumField(); i++ {
   328 				if err != nil {
   441 				mtypef, mvalf := mtype.Field(i), mval.Field(i)
   329 					return nil, err
   442 				opts := tomlOptions(mtypef, e.annotation)
       
   443 				if opts.include && ((mtypef.Type.Kind() != reflect.Interface && !opts.omitempty) || !isZero(mvalf)) {
       
   444 					val, err := e.valueToToml(mtypef.Type, mvalf)
       
   445 					if err != nil {
       
   446 						return nil, err
       
   447 					}
       
   448 					if tree, ok := val.(*Tree); ok && mtypef.Anonymous && !opts.nameFromTag && !e.promoteAnon {
       
   449 						e.appendTree(tval, tree)
       
   450 					} else {
       
   451 						val = e.wrapTomlValue(val, tval)
       
   452 						tval.SetPathWithOptions([]string{opts.name}, SetOptions{
       
   453 							Comment:   opts.comment,
       
   454 							Commented: opts.commented,
       
   455 							Multiline: opts.multiline,
       
   456 							Literal:   opts.literal,
       
   457 						}, val)
       
   458 					}
   330 				}
   459 				}
   331 
       
   332 				tval.SetWithOptions(opts.name, SetOptions{
       
   333 					Comment:   opts.comment,
       
   334 					Commented: opts.commented,
       
   335 					Multiline: opts.multiline,
       
   336 				}, val)
       
   337 			}
   460 			}
   338 		}
   461 		}
   339 	case reflect.Map:
   462 	case reflect.Map:
   340 		keys := mval.MapKeys()
   463 		keys := mval.MapKeys()
   341 		if e.order == OrderPreserve && len(keys) > 0 {
   464 		if e.order == OrderPreserve && len(keys) > 0 {
   356 				}
   479 				}
   357 			}
   480 			}
   358 		}
   481 		}
   359 		for _, key := range keys {
   482 		for _, key := range keys {
   360 			mvalf := mval.MapIndex(key)
   483 			mvalf := mval.MapIndex(key)
       
   484 			if (mtype.Elem().Kind() == reflect.Ptr || mtype.Elem().Kind() == reflect.Interface) && mvalf.IsNil() {
       
   485 				continue
       
   486 			}
   361 			val, err := e.valueToToml(mtype.Elem(), mvalf)
   487 			val, err := e.valueToToml(mtype.Elem(), mvalf)
   362 			if err != nil {
   488 			if err != nil {
   363 				return nil, err
   489 				return nil, err
   364 			}
   490 			}
       
   491 			val = e.wrapTomlValue(val, tval)
   365 			if e.quoteMapKeys {
   492 			if e.quoteMapKeys {
   366 				keyStr, err := tomlValueStringRepresentation(key.String(), "", e.arraysOneElementPerLine)
   493 				keyStr, err := tomlValueStringRepresentation(key.String(), "", "", e.order, e.arraysOneElementPerLine)
   367 				if err != nil {
   494 				if err != nil {
   368 					return nil, err
   495 					return nil, err
   369 				}
   496 				}
   370 				tval.SetPath([]string{keyStr}, val)
   497 				tval.SetPath([]string{keyStr}, val)
   371 			} else {
   498 			} else {
   372 				tval.Set(key.String(), val)
   499 				tval.SetPath([]string{key.String()}, val)
   373 			}
   500 			}
   374 		}
   501 		}
   375 	}
   502 	}
   376 	return tval, nil
   503 	return tval, nil
   377 }
   504 }
   402 	return tval, nil
   529 	return tval, nil
   403 }
   530 }
   404 
   531 
   405 // Convert given marshal value to toml value
   532 // Convert given marshal value to toml value
   406 func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
   533 func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) {
   407 	e.line++
       
   408 	if mtype.Kind() == reflect.Ptr {
   534 	if mtype.Kind() == reflect.Ptr {
   409 		return e.valueToToml(mtype.Elem(), mval.Elem())
   535 		switch {
       
   536 		case isCustomMarshaler(mtype):
       
   537 			return callCustomMarshaler(mval)
       
   538 		case isTextMarshaler(mtype):
       
   539 			b, err := callTextMarshaler(mval)
       
   540 			return string(b), err
       
   541 		default:
       
   542 			return e.valueToToml(mtype.Elem(), mval.Elem())
       
   543 		}
       
   544 	}
       
   545 	if mtype.Kind() == reflect.Interface {
       
   546 		return e.valueToToml(mval.Elem().Type(), mval.Elem())
   410 	}
   547 	}
   411 	switch {
   548 	switch {
   412 	case isCustomMarshaler(mtype):
   549 	case isCustomMarshaler(mtype):
   413 		return callCustomMarshaler(mval)
   550 		return callCustomMarshaler(mval)
       
   551 	case isTextMarshaler(mtype):
       
   552 		b, err := callTextMarshaler(mval)
       
   553 		return string(b), err
   414 	case isTree(mtype):
   554 	case isTree(mtype):
   415 		return e.valueToTree(mtype, mval)
   555 		return e.valueToTree(mtype, mval)
       
   556 	case isOtherSequence(mtype), isCustomMarshalerSequence(mtype), isTextMarshalerSequence(mtype):
       
   557 		return e.valueToOtherSlice(mtype, mval)
   416 	case isTreeSequence(mtype):
   558 	case isTreeSequence(mtype):
   417 		return e.valueToTreeSlice(mtype, mval)
   559 		return e.valueToTreeSlice(mtype, mval)
   418 	case isOtherSequence(mtype):
       
   419 		return e.valueToOtherSlice(mtype, mval)
       
   420 	default:
   560 	default:
   421 		switch mtype.Kind() {
   561 		switch mtype.Kind() {
   422 		case reflect.Bool:
   562 		case reflect.Bool:
   423 			return mval.Bool(), nil
   563 			return mval.Bool(), nil
   424 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   564 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   436 			return mval.Interface(), nil
   576 			return mval.Interface(), nil
   437 		default:
   577 		default:
   438 			return nil, fmt.Errorf("Marshal can't handle %v(%v)", mtype, mtype.Kind())
   578 			return nil, fmt.Errorf("Marshal can't handle %v(%v)", mtype, mtype.Kind())
   439 		}
   579 		}
   440 	}
   580 	}
       
   581 }
       
   582 
       
   583 func (e *Encoder) appendTree(t, o *Tree) error {
       
   584 	for key, value := range o.values {
       
   585 		if _, ok := t.values[key]; ok {
       
   586 			continue
       
   587 		}
       
   588 		if tomlValue, ok := value.(*tomlValue); ok {
       
   589 			tomlValue.position.Col = t.position.Col
       
   590 		}
       
   591 		t.values[key] = value
       
   592 	}
       
   593 	return nil
       
   594 }
       
   595 
       
   596 // Create a toml value with the current line number as the position line
       
   597 func (e *Encoder) wrapTomlValue(val interface{}, parent *Tree) interface{} {
       
   598 	_, isTree := val.(*Tree)
       
   599 	_, isTreeS := val.([]*Tree)
       
   600 	if isTree || isTreeS {
       
   601 		e.line++
       
   602 		return val
       
   603 	}
       
   604 
       
   605 	ret := &tomlValue{
       
   606 		value: val,
       
   607 		position: Position{
       
   608 			e.line,
       
   609 			parent.position.Col,
       
   610 		},
       
   611 	}
       
   612 	e.line++
       
   613 	return ret
   441 }
   614 }
   442 
   615 
   443 // Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v.
   616 // Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v.
   444 // Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for
   617 // Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for
   445 // sub-structs, and only definite types can be unmarshaled.
   618 // sub-structs, and only definite types can be unmarshaled.
   490 type Decoder struct {
   663 type Decoder struct {
   491 	r    io.Reader
   664 	r    io.Reader
   492 	tval *Tree
   665 	tval *Tree
   493 	encOpts
   666 	encOpts
   494 	tagName string
   667 	tagName string
       
   668 	strict  bool
       
   669 	visitor visitorState
   495 }
   670 }
   496 
   671 
   497 // NewDecoder returns a new decoder that reads from r.
   672 // NewDecoder returns a new decoder that reads from r.
   498 func NewDecoder(r io.Reader) *Decoder {
   673 func NewDecoder(r io.Reader) *Decoder {
   499 	return &Decoder{
   674 	return &Decoder{
   520 func (d *Decoder) SetTagName(v string) *Decoder {
   695 func (d *Decoder) SetTagName(v string) *Decoder {
   521 	d.tagName = v
   696 	d.tagName = v
   522 	return d
   697 	return d
   523 }
   698 }
   524 
   699 
       
   700 // Strict allows changing to strict decoding. Any fields that are found in the
       
   701 // input data and do not have a corresponding struct member cause an error.
       
   702 func (d *Decoder) Strict(strict bool) *Decoder {
       
   703 	d.strict = strict
       
   704 	return d
       
   705 }
       
   706 
   525 func (d *Decoder) unmarshal(v interface{}) error {
   707 func (d *Decoder) unmarshal(v interface{}) error {
   526 	mtype := reflect.TypeOf(v)
   708 	mtype := reflect.TypeOf(v)
       
   709 	if mtype == nil {
       
   710 		return errors.New("nil cannot be unmarshaled from TOML")
       
   711 	}
   527 	if mtype.Kind() != reflect.Ptr {
   712 	if mtype.Kind() != reflect.Ptr {
   528 		return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
   713 		return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
   529 	}
   714 	}
   530 
   715 
   531 	elem := mtype.Elem()
   716 	elem := mtype.Elem()
   532 
   717 
   533 	switch elem.Kind() {
   718 	switch elem.Kind() {
   534 	case reflect.Struct, reflect.Map:
   719 	case reflect.Struct, reflect.Map:
       
   720 	case reflect.Interface:
       
   721 		elem = mapStringInterfaceType
   535 	default:
   722 	default:
   536 		return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
   723 		return errors.New("only a pointer to struct or map can be unmarshaled from TOML")
   537 	}
   724 	}
   538 
   725 
       
   726 	if reflect.ValueOf(v).IsNil() {
       
   727 		return errors.New("nil pointer cannot be unmarshaled from TOML")
       
   728 	}
       
   729 
   539 	vv := reflect.ValueOf(v).Elem()
   730 	vv := reflect.ValueOf(v).Elem()
       
   731 
       
   732 	if d.strict {
       
   733 		d.visitor = newVisitorState(d.tval)
       
   734 	}
   540 
   735 
   541 	sval, err := d.valueFromTree(elem, d.tval, &vv)
   736 	sval, err := d.valueFromTree(elem, d.tval, &vv)
   542 	if err != nil {
   737 	if err != nil {
       
   738 		return err
       
   739 	}
       
   740 	if err := d.visitor.validate(); err != nil {
   543 		return err
   741 		return err
   544 	}
   742 	}
   545 	reflect.ValueOf(v).Elem().Set(sval)
   743 	reflect.ValueOf(v).Elem().Set(sval)
   546 	return nil
   744 	return nil
   547 }
   745 }
   550 // is non-nil, merge fields into the given value instead of allocating a new one.
   748 // 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) {
   749 func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree, mval1 *reflect.Value) (reflect.Value, error) {
   552 	if mtype.Kind() == reflect.Ptr {
   750 	if mtype.Kind() == reflect.Ptr {
   553 		return d.unwrapPointer(mtype, tval, mval1)
   751 		return d.unwrapPointer(mtype, tval, mval1)
   554 	}
   752 	}
       
   753 
       
   754 	// Check if pointer to value implements the Unmarshaler interface.
       
   755 	if mvalPtr := reflect.New(mtype); isCustomUnmarshaler(mvalPtr.Type()) {
       
   756 		d.visitor.visitAll()
       
   757 
       
   758 		if tval == nil {
       
   759 			return mvalPtr.Elem(), nil
       
   760 		}
       
   761 
       
   762 		if err := callCustomUnmarshaler(mvalPtr, tval.ToMap()); err != nil {
       
   763 			return reflect.ValueOf(nil), fmt.Errorf("unmarshal toml: %v", err)
       
   764 		}
       
   765 		return mvalPtr.Elem(), nil
       
   766 	}
       
   767 
   555 	var mval reflect.Value
   768 	var mval reflect.Value
   556 	switch mtype.Kind() {
   769 	switch mtype.Kind() {
   557 	case reflect.Struct:
   770 	case reflect.Struct:
   558 		if mval1 != nil {
   771 		if mval1 != nil {
   559 			mval = *mval1
   772 			mval = *mval1
   560 		} else {
   773 		} else {
   561 			mval = reflect.New(mtype).Elem()
   774 			mval = reflect.New(mtype).Elem()
   562 		}
   775 		}
   563 
   776 
   564 		for i := 0; i < mtype.NumField(); i++ {
   777 		switch mval.Interface().(type) {
   565 			mtypef := mtype.Field(i)
   778 		case Tree:
   566 			an := annotation{tag: d.tagName}
   779 			mval.Set(reflect.ValueOf(tval).Elem())
   567 			opts := tomlOptions(mtypef, an)
   780 		default:
   568 			if opts.include {
   781 			for i := 0; i < mtype.NumField(); i++ {
       
   782 				mtypef := mtype.Field(i)
       
   783 				an := annotation{tag: d.tagName}
       
   784 				opts := tomlOptions(mtypef, an)
       
   785 				if !opts.include {
       
   786 					continue
       
   787 				}
   569 				baseKey := opts.name
   788 				baseKey := opts.name
   570 				keysToTry := []string{
   789 				keysToTry := []string{
   571 					baseKey,
   790 					baseKey,
   572 					strings.ToLower(baseKey),
   791 					strings.ToLower(baseKey),
   573 					strings.ToTitle(baseKey),
   792 					strings.ToTitle(baseKey),
   574 					strings.ToLower(string(baseKey[0])) + baseKey[1:],
   793 					strings.ToLower(string(baseKey[0])) + baseKey[1:],
   575 				}
   794 				}
   576 
   795 
   577 				found := false
   796 				found := false
   578 				for _, key := range keysToTry {
   797 				if tval != nil {
   579 					exists := tval.Has(key)
   798 					for _, key := range keysToTry {
   580 					if !exists {
   799 						exists := tval.HasPath([]string{key})
   581 						continue
   800 						if !exists {
       
   801 							continue
       
   802 						}
       
   803 
       
   804 						d.visitor.push(key)
       
   805 						val := tval.GetPath([]string{key})
       
   806 						fval := mval.Field(i)
       
   807 						mvalf, err := d.valueFromToml(mtypef.Type, val, &fval)
       
   808 						if err != nil {
       
   809 							return mval, formatError(err, tval.GetPositionPath([]string{key}))
       
   810 						}
       
   811 						mval.Field(i).Set(mvalf)
       
   812 						found = true
       
   813 						d.visitor.pop()
       
   814 						break
   582 					}
   815 					}
   583 					val := tval.Get(key)
       
   584 					fval := mval.Field(i)
       
   585 					mvalf, err := d.valueFromToml(mtypef.Type, val, &fval)
       
   586 					if err != nil {
       
   587 						return mval, formatError(err, tval.GetPosition(key))
       
   588 					}
       
   589 					mval.Field(i).Set(mvalf)
       
   590 					found = true
       
   591 					break
       
   592 				}
   816 				}
   593 
   817 
   594 				if !found && opts.defaultValue != "" {
   818 				if !found && opts.defaultValue != "" {
   595 					mvalf := mval.Field(i)
   819 					mvalf := mval.Field(i)
   596 					var val interface{}
   820 					var val interface{}
   597 					var err error
   821 					var err error
   598 					switch mvalf.Kind() {
   822 					switch mvalf.Kind() {
       
   823 					case reflect.String:
       
   824 						val = opts.defaultValue
   599 					case reflect.Bool:
   825 					case reflect.Bool:
   600 						val, err = strconv.ParseBool(opts.defaultValue)
   826 						val, err = strconv.ParseBool(opts.defaultValue)
   601 						if err != nil {
   827 					case reflect.Uint:
   602 							return mval.Field(i), err
   828 						val, err = strconv.ParseUint(opts.defaultValue, 10, 0)
       
   829 					case reflect.Uint8:
       
   830 						val, err = strconv.ParseUint(opts.defaultValue, 10, 8)
       
   831 					case reflect.Uint16:
       
   832 						val, err = strconv.ParseUint(opts.defaultValue, 10, 16)
       
   833 					case reflect.Uint32:
       
   834 						val, err = strconv.ParseUint(opts.defaultValue, 10, 32)
       
   835 					case reflect.Uint64:
       
   836 						val, err = strconv.ParseUint(opts.defaultValue, 10, 64)
       
   837 					case reflect.Int:
       
   838 						val, err = strconv.ParseInt(opts.defaultValue, 10, 0)
       
   839 					case reflect.Int8:
       
   840 						val, err = strconv.ParseInt(opts.defaultValue, 10, 8)
       
   841 					case reflect.Int16:
       
   842 						val, err = strconv.ParseInt(opts.defaultValue, 10, 16)
       
   843 					case reflect.Int32:
       
   844 						val, err = strconv.ParseInt(opts.defaultValue, 10, 32)
       
   845 					case reflect.Int64:
       
   846 						// Check if the provided number has a non-numeric extension.
       
   847 						var hasExtension bool
       
   848 						if len(opts.defaultValue) > 0 {
       
   849 							lastChar := opts.defaultValue[len(opts.defaultValue)-1]
       
   850 							if lastChar < '0' || lastChar > '9' {
       
   851 								hasExtension = true
       
   852 							}
   603 						}
   853 						}
   604 					case reflect.Int:
   854 						// If the value is a time.Duration with extension, parse as duration.
   605 						val, err = strconv.Atoi(opts.defaultValue)
   855 						// If the value is an int64 or a time.Duration without extension, parse as number.
   606 						if err != nil {
   856 						if hasExtension && mvalf.Type().String() == "time.Duration" {
   607 							return mval.Field(i), err
   857 							val, err = time.ParseDuration(opts.defaultValue)
       
   858 						} else {
       
   859 							val, err = strconv.ParseInt(opts.defaultValue, 10, 64)
   608 						}
   860 						}
   609 					case reflect.String:
   861 					case reflect.Float32:
   610 						val = opts.defaultValue
   862 						val, err = strconv.ParseFloat(opts.defaultValue, 32)
   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:
   863 					case reflect.Float64:
   617 						val, err = strconv.ParseFloat(opts.defaultValue, 64)
   864 						val, err = strconv.ParseFloat(opts.defaultValue, 64)
   618 						if err != nil {
       
   619 							return mval.Field(i), err
       
   620 						}
       
   621 					default:
   865 					default:
   622 						return mval.Field(i), fmt.Errorf("unsuported field type for default option")
   866 						return mvalf, fmt.Errorf("unsupported field type for default option")
   623 					}
   867 					}
   624 					mval.Field(i).Set(reflect.ValueOf(val))
   868 
       
   869 					if err != nil {
       
   870 						return mvalf, err
       
   871 					}
       
   872 					mvalf.Set(reflect.ValueOf(val).Convert(mvalf.Type()))
   625 				}
   873 				}
   626 
   874 
   627 				// save the old behavior above and try to check anonymous structs
   875 				// save the old behavior above and try to check structs
   628 				if !found && opts.defaultValue == "" && mtypef.Anonymous && mtypef.Type.Kind() == reflect.Struct {
   876 				if !found && opts.defaultValue == "" && mtypef.Type.Kind() == reflect.Struct {
   629 					v, err := d.valueFromTree(mtypef.Type, tval, nil)
   877 					tmpTval := tval
       
   878 					if !mtypef.Anonymous {
       
   879 						tmpTval = nil
       
   880 					}
       
   881 					fval := mval.Field(i)
       
   882 					v, err := d.valueFromTree(mtypef.Type, tmpTval, &fval)
   630 					if err != nil {
   883 					if err != nil {
   631 						return v, err
   884 						return v, err
   632 					}
   885 					}
   633 					mval.Field(i).Set(v)
   886 					mval.Field(i).Set(v)
   634 				}
   887 				}
   635 			}
   888 			}
   636 		}
   889 		}
   637 	case reflect.Map:
   890 	case reflect.Map:
   638 		mval = reflect.MakeMap(mtype)
   891 		mval = reflect.MakeMap(mtype)
   639 		for _, key := range tval.Keys() {
   892 		for _, key := range tval.Keys() {
       
   893 			d.visitor.push(key)
   640 			// TODO: path splits key
   894 			// TODO: path splits key
   641 			val := tval.GetPath([]string{key})
   895 			val := tval.GetPath([]string{key})
   642 			mvalf, err := d.valueFromToml(mtype.Elem(), val, nil)
   896 			mvalf, err := d.valueFromToml(mtype.Elem(), val, nil)
   643 			if err != nil {
   897 			if err != nil {
   644 				return mval, formatError(err, tval.GetPosition(key))
   898 				return mval, formatError(err, tval.GetPositionPath([]string{key}))
   645 			}
   899 			}
   646 			mval.SetMapIndex(reflect.ValueOf(key).Convert(mtype.Key()), mvalf)
   900 			mval.SetMapIndex(reflect.ValueOf(key).Convert(mtype.Key()), mvalf)
       
   901 			d.visitor.pop()
   647 		}
   902 		}
   648 	}
   903 	}
   649 	return mval, nil
   904 	return mval, nil
   650 }
   905 }
   651 
   906 
   652 // Convert toml value to marshal struct/map slice, using marshal type
   907 // Convert toml value to marshal struct/map slice, using marshal type
   653 func (d *Decoder) valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) {
   908 func (d *Decoder) valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) {
   654 	mval := reflect.MakeSlice(mtype, len(tval), len(tval))
   909 	mval, err := makeSliceOrArray(mtype, len(tval))
       
   910 	if err != nil {
       
   911 		return mval, err
       
   912 	}
       
   913 
   655 	for i := 0; i < len(tval); i++ {
   914 	for i := 0; i < len(tval); i++ {
       
   915 		d.visitor.push(strconv.Itoa(i))
   656 		val, err := d.valueFromTree(mtype.Elem(), tval[i], nil)
   916 		val, err := d.valueFromTree(mtype.Elem(), tval[i], nil)
   657 		if err != nil {
   917 		if err != nil {
   658 			return mval, err
   918 			return mval, err
   659 		}
   919 		}
   660 		mval.Index(i).Set(val)
   920 		mval.Index(i).Set(val)
       
   921 		d.visitor.pop()
   661 	}
   922 	}
   662 	return mval, nil
   923 	return mval, nil
   663 }
   924 }
   664 
   925 
   665 // Convert toml value to marshal primitive slice, using marshal type
   926 // Convert toml value to marshal primitive slice, using marshal type
   666 func (d *Decoder) valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value, error) {
   927 func (d *Decoder) valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value, error) {
   667 	mval := reflect.MakeSlice(mtype, len(tval), len(tval))
   928 	mval, err := makeSliceOrArray(mtype, len(tval))
       
   929 	if err != nil {
       
   930 		return mval, err
       
   931 	}
       
   932 
   668 	for i := 0; i < len(tval); i++ {
   933 	for i := 0; i < len(tval); i++ {
   669 		val, err := d.valueFromToml(mtype.Elem(), tval[i], nil)
   934 		val, err := d.valueFromToml(mtype.Elem(), tval[i], nil)
   670 		if err != nil {
   935 		if err != nil {
   671 			return mval, err
   936 			return mval, err
   672 		}
   937 		}
   673 		mval.Index(i).Set(val)
   938 		mval.Index(i).Set(val)
       
   939 	}
       
   940 	return mval, nil
       
   941 }
       
   942 
       
   943 // Convert toml value to marshal primitive slice, using marshal type
       
   944 func (d *Decoder) valueFromOtherSliceI(mtype reflect.Type, tval interface{}) (reflect.Value, error) {
       
   945 	val := reflect.ValueOf(tval)
       
   946 	length := val.Len()
       
   947 
       
   948 	mval, err := makeSliceOrArray(mtype, length)
       
   949 	if err != nil {
       
   950 		return mval, err
       
   951 	}
       
   952 
       
   953 	for i := 0; i < length; i++ {
       
   954 		val, err := d.valueFromToml(mtype.Elem(), val.Index(i).Interface(), nil)
       
   955 		if err != nil {
       
   956 			return mval, err
       
   957 		}
       
   958 		mval.Index(i).Set(val)
       
   959 	}
       
   960 	return mval, nil
       
   961 }
       
   962 
       
   963 // Create a new slice or a new array with specified length
       
   964 func makeSliceOrArray(mtype reflect.Type, tLength int) (reflect.Value, error) {
       
   965 	var mval reflect.Value
       
   966 	switch mtype.Kind() {
       
   967 	case reflect.Slice:
       
   968 		mval = reflect.MakeSlice(mtype, tLength, tLength)
       
   969 	case reflect.Array:
       
   970 		mval = reflect.New(reflect.ArrayOf(mtype.Len(), mtype.Elem())).Elem()
       
   971 		if tLength > mtype.Len() {
       
   972 			return mval, fmt.Errorf("unmarshal: TOML array length (%v) exceeds destination array length (%v)", tLength, mtype.Len())
       
   973 		}
   674 	}
   974 	}
   675 	return mval, nil
   975 	return mval, nil
   676 }
   976 }
   677 
   977 
   678 // Convert toml value to marshal value, using marshal type. When mval1 is non-nil
   978 // Convert toml value to marshal value, using marshal type. When mval1 is non-nil
   690 		}
   990 		}
   691 
   991 
   692 		if isTree(mtype) {
   992 		if isTree(mtype) {
   693 			return d.valueFromTree(mtype, t, mval11)
   993 			return d.valueFromTree(mtype, t, mval11)
   694 		}
   994 		}
       
   995 
       
   996 		if mtype.Kind() == reflect.Interface {
       
   997 			if mval1 == nil || mval1.IsNil() {
       
   998 				return d.valueFromTree(reflect.TypeOf(map[string]interface{}{}), t, nil)
       
   999 			} else {
       
  1000 				return d.valueFromToml(mval1.Elem().Type(), t, nil)
       
  1001 			}
       
  1002 		}
       
  1003 
   695 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
  1004 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
   696 	case []*Tree:
  1005 	case []*Tree:
   697 		if isTreeSequence(mtype) {
  1006 		if isTreeSequence(mtype) {
   698 			return d.valueFromTreeSlice(mtype, t)
  1007 			return d.valueFromTreeSlice(mtype, t)
   699 		}
  1008 		}
       
  1009 		if mtype.Kind() == reflect.Interface {
       
  1010 			if mval1 == nil || mval1.IsNil() {
       
  1011 				return d.valueFromTreeSlice(reflect.TypeOf([]map[string]interface{}{}), t)
       
  1012 			} else {
       
  1013 				ival := mval1.Elem()
       
  1014 				return d.valueFromToml(mval1.Elem().Type(), t, &ival)
       
  1015 			}
       
  1016 		}
   700 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
  1017 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
   701 	case []interface{}:
  1018 	case []interface{}:
       
  1019 		d.visitor.visit()
   702 		if isOtherSequence(mtype) {
  1020 		if isOtherSequence(mtype) {
   703 			return d.valueFromOtherSlice(mtype, t)
  1021 			return d.valueFromOtherSlice(mtype, t)
   704 		}
  1022 		}
       
  1023 		if mtype.Kind() == reflect.Interface {
       
  1024 			if mval1 == nil || mval1.IsNil() {
       
  1025 				return d.valueFromOtherSlice(reflect.TypeOf([]interface{}{}), t)
       
  1026 			} else {
       
  1027 				ival := mval1.Elem()
       
  1028 				return d.valueFromToml(mval1.Elem().Type(), t, &ival)
       
  1029 			}
       
  1030 		}
   705 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
  1031 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
   706 	default:
  1032 	default:
       
  1033 		d.visitor.visit()
       
  1034 		mvalPtr := reflect.New(mtype)
       
  1035 
       
  1036 		// Check if pointer to value implements the Unmarshaler interface.
       
  1037 		if isCustomUnmarshaler(mvalPtr.Type()) {
       
  1038 			if err := callCustomUnmarshaler(mvalPtr, tval); err != nil {
       
  1039 				return reflect.ValueOf(nil), fmt.Errorf("unmarshal toml: %v", err)
       
  1040 			}
       
  1041 			return mvalPtr.Elem(), nil
       
  1042 		}
       
  1043 
       
  1044 		// Check if pointer to value implements the encoding.TextUnmarshaler.
       
  1045 		if isTextUnmarshaler(mvalPtr.Type()) && !isTimeType(mtype) {
       
  1046 			if err := d.unmarshalText(tval, mvalPtr); err != nil {
       
  1047 				return reflect.ValueOf(nil), fmt.Errorf("unmarshal text: %v", err)
       
  1048 			}
       
  1049 			return mvalPtr.Elem(), nil
       
  1050 		}
       
  1051 
   707 		switch mtype.Kind() {
  1052 		switch mtype.Kind() {
   708 		case reflect.Bool, reflect.Struct:
  1053 		case reflect.Bool, reflect.Struct:
   709 			val := reflect.ValueOf(tval)
  1054 			val := reflect.ValueOf(tval)
   710 
  1055 
   711 			switch val.Type() {
  1056 			switch val.Type() {
   752 				if err != nil {
  1097 				if err != nil {
   753 					return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v. %s", tval, tval, mtype.String(), err)
  1098 					return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v. %s", tval, tval, mtype.String(), err)
   754 				}
  1099 				}
   755 				return reflect.ValueOf(d), nil
  1100 				return reflect.ValueOf(d), nil
   756 			}
  1101 			}
   757 			if !val.Type().ConvertibleTo(mtype) {
  1102 			if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Float64 {
   758 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
  1103 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   759 			}
  1104 			}
   760 			if reflect.Indirect(reflect.New(mtype)).OverflowInt(val.Convert(mtype).Int()) {
  1105 			if reflect.Indirect(reflect.New(mtype)).OverflowInt(val.Convert(reflect.TypeOf(int64(0))).Int()) {
   761 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
  1106 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
   762 			}
  1107 			}
   763 
  1108 
   764 			return val.Convert(mtype), nil
  1109 			return val.Convert(mtype), nil
   765 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1110 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   766 			val := reflect.ValueOf(tval)
  1111 			val := reflect.ValueOf(tval)
   767 			if !val.Type().ConvertibleTo(mtype) {
  1112 			if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Float64 {
   768 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
  1113 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   769 			}
  1114 			}
   770 
  1115 
   771 			if val.Convert(reflect.TypeOf(int(1))).Int() < 0 {
  1116 			if val.Convert(reflect.TypeOf(int(1))).Int() < 0 {
   772 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String())
  1117 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String())
   773 			}
  1118 			}
   774 			if reflect.Indirect(reflect.New(mtype)).OverflowUint(uint64(val.Convert(mtype).Uint())) {
  1119 			if reflect.Indirect(reflect.New(mtype)).OverflowUint(val.Convert(reflect.TypeOf(uint64(0))).Uint()) {
   775 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
  1120 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
   776 			}
  1121 			}
   777 
  1122 
   778 			return val.Convert(mtype), nil
  1123 			return val.Convert(mtype), nil
   779 		case reflect.Float32, reflect.Float64:
  1124 		case reflect.Float32, reflect.Float64:
   780 			val := reflect.ValueOf(tval)
  1125 			val := reflect.ValueOf(tval)
   781 			if !val.Type().ConvertibleTo(mtype) {
  1126 			if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Int64 {
   782 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
  1127 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
   783 			}
  1128 			}
   784 			if reflect.Indirect(reflect.New(mtype)).OverflowFloat(val.Convert(mtype).Float()) {
  1129 			if reflect.Indirect(reflect.New(mtype)).OverflowFloat(val.Convert(reflect.TypeOf(float64(0))).Float()) {
   785 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
  1130 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String())
   786 			}
  1131 			}
   787 
  1132 
   788 			return val.Convert(mtype), nil
  1133 			return val.Convert(mtype), nil
       
  1134 		case reflect.Interface:
       
  1135 			if mval1 == nil || mval1.IsNil() {
       
  1136 				return reflect.ValueOf(tval), nil
       
  1137 			} else {
       
  1138 				ival := mval1.Elem()
       
  1139 				return d.valueFromToml(mval1.Elem().Type(), t, &ival)
       
  1140 			}
       
  1141 		case reflect.Slice, reflect.Array:
       
  1142 			if isOtherSequence(mtype) && isOtherSequence(reflect.TypeOf(t)) {
       
  1143 				return d.valueFromOtherSliceI(mtype, t)
       
  1144 			}
       
  1145 			return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind())
   789 		default:
  1146 		default:
   790 			return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind())
  1147 			return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind())
   791 		}
  1148 		}
   792 	}
  1149 	}
   793 }
  1150 }
   794 
  1151 
   795 func (d *Decoder) unwrapPointer(mtype reflect.Type, tval interface{}, mval1 *reflect.Value) (reflect.Value, error) {
  1152 func (d *Decoder) unwrapPointer(mtype reflect.Type, tval interface{}, mval1 *reflect.Value) (reflect.Value, error) {
   796 	var melem *reflect.Value
  1153 	var melem *reflect.Value
   797 
  1154 
   798 	if mval1 != nil && !mval1.IsNil() && mtype.Elem().Kind() == reflect.Struct {
  1155 	if mval1 != nil && !mval1.IsNil() && (mtype.Elem().Kind() == reflect.Struct || mtype.Elem().Kind() == reflect.Interface) {
   799 		elem := mval1.Elem()
  1156 		elem := mval1.Elem()
   800 		melem = &elem
  1157 		melem = &elem
   801 	}
  1158 	}
   802 
  1159 
   803 	val, err := d.valueFromToml(mtype.Elem(), tval, melem)
  1160 	val, err := d.valueFromToml(mtype.Elem(), tval, melem)
   805 		return reflect.ValueOf(nil), err
  1162 		return reflect.ValueOf(nil), err
   806 	}
  1163 	}
   807 	mval := reflect.New(mtype.Elem())
  1164 	mval := reflect.New(mtype.Elem())
   808 	mval.Elem().Set(val)
  1165 	mval.Elem().Set(val)
   809 	return mval, nil
  1166 	return mval, nil
       
  1167 }
       
  1168 
       
  1169 func (d *Decoder) unmarshalText(tval interface{}, mval reflect.Value) error {
       
  1170 	var buf bytes.Buffer
       
  1171 	fmt.Fprint(&buf, tval)
       
  1172 	return callTextUnmarshaler(mval, buf.Bytes())
   810 }
  1173 }
   811 
  1174 
   812 func tomlOptions(vf reflect.StructField, an annotation) tomlOpts {
  1175 func tomlOptions(vf reflect.StructField, an annotation) tomlOpts {
   813 	tag := vf.Tag.Get(an.tag)
  1176 	tag := vf.Tag.Get(an.tag)
   814 	parse := strings.Split(tag, ",")
  1177 	parse := strings.Split(tag, ",")
   816 	if c := vf.Tag.Get(an.comment); c != "" {
  1179 	if c := vf.Tag.Get(an.comment); c != "" {
   817 		comment = c
  1180 		comment = c
   818 	}
  1181 	}
   819 	commented, _ := strconv.ParseBool(vf.Tag.Get(an.commented))
  1182 	commented, _ := strconv.ParseBool(vf.Tag.Get(an.commented))
   820 	multiline, _ := strconv.ParseBool(vf.Tag.Get(an.multiline))
  1183 	multiline, _ := strconv.ParseBool(vf.Tag.Get(an.multiline))
       
  1184 	literal, _ := strconv.ParseBool(vf.Tag.Get(an.literal))
   821 	defaultValue := vf.Tag.Get(tagDefault)
  1185 	defaultValue := vf.Tag.Get(tagDefault)
   822 	result := tomlOpts{
  1186 	result := tomlOpts{
   823 		name:         vf.Name,
  1187 		name:         vf.Name,
       
  1188 		nameFromTag:  false,
   824 		comment:      comment,
  1189 		comment:      comment,
   825 		commented:    commented,
  1190 		commented:    commented,
   826 		multiline:    multiline,
  1191 		multiline:    multiline,
       
  1192 		literal:      literal,
   827 		include:      true,
  1193 		include:      true,
   828 		omitempty:    false,
  1194 		omitempty:    false,
   829 		defaultValue: defaultValue,
  1195 		defaultValue: defaultValue,
   830 	}
  1196 	}
   831 	if parse[0] != "" {
  1197 	if parse[0] != "" {
   832 		if parse[0] == "-" && len(parse) == 1 {
  1198 		if parse[0] == "-" && len(parse) == 1 {
   833 			result.include = false
  1199 			result.include = false
   834 		} else {
  1200 		} else {
   835 			result.name = strings.Trim(parse[0], " ")
  1201 			result.name = strings.Trim(parse[0], " ")
       
  1202 			result.nameFromTag = true
   836 		}
  1203 		}
   837 	}
  1204 	}
   838 	if vf.PkgPath != "" {
  1205 	if vf.PkgPath != "" {
   839 		result.include = false
  1206 		result.include = false
   840 	}
  1207 	}
   847 	return result
  1214 	return result
   848 }
  1215 }
   849 
  1216 
   850 func isZero(val reflect.Value) bool {
  1217 func isZero(val reflect.Value) bool {
   851 	switch val.Type().Kind() {
  1218 	switch val.Type().Kind() {
   852 	case reflect.Map:
  1219 	case reflect.Slice, reflect.Array, reflect.Map:
   853 		fallthrough
       
   854 	case reflect.Array:
       
   855 		fallthrough
       
   856 	case reflect.Slice:
       
   857 		return val.Len() == 0
  1220 		return val.Len() == 0
   858 	default:
  1221 	default:
   859 		return reflect.DeepEqual(val.Interface(), reflect.Zero(val.Type()).Interface())
  1222 		return reflect.DeepEqual(val.Interface(), reflect.Zero(val.Type()).Interface())
   860 	}
  1223 	}
   861 }
  1224 }
   864 	if err.Error()[0] == '(' { // Error already contains position information
  1227 	if err.Error()[0] == '(' { // Error already contains position information
   865 		return err
  1228 		return err
   866 	}
  1229 	}
   867 	return fmt.Errorf("%s: %s", pos, err)
  1230 	return fmt.Errorf("%s: %s", pos, err)
   868 }
  1231 }
       
  1232 
       
  1233 // visitorState keeps track of which keys were unmarshaled.
       
  1234 type visitorState struct {
       
  1235 	tree   *Tree
       
  1236 	path   []string
       
  1237 	keys   map[string]struct{}
       
  1238 	active bool
       
  1239 }
       
  1240 
       
  1241 func newVisitorState(tree *Tree) visitorState {
       
  1242 	path, result := []string{}, map[string]struct{}{}
       
  1243 	insertKeys(path, result, tree)
       
  1244 	return visitorState{
       
  1245 		tree:   tree,
       
  1246 		path:   path[:0],
       
  1247 		keys:   result,
       
  1248 		active: true,
       
  1249 	}
       
  1250 }
       
  1251 
       
  1252 func (s *visitorState) push(key string) {
       
  1253 	if s.active {
       
  1254 		s.path = append(s.path, key)
       
  1255 	}
       
  1256 }
       
  1257 
       
  1258 func (s *visitorState) pop() {
       
  1259 	if s.active {
       
  1260 		s.path = s.path[:len(s.path)-1]
       
  1261 	}
       
  1262 }
       
  1263 
       
  1264 func (s *visitorState) visit() {
       
  1265 	if s.active {
       
  1266 		delete(s.keys, strings.Join(s.path, "."))
       
  1267 	}
       
  1268 }
       
  1269 
       
  1270 func (s *visitorState) visitAll() {
       
  1271 	if s.active {
       
  1272 		for k := range s.keys {
       
  1273 			if strings.HasPrefix(k, strings.Join(s.path, ".")) {
       
  1274 				delete(s.keys, k)
       
  1275 			}
       
  1276 		}
       
  1277 	}
       
  1278 }
       
  1279 
       
  1280 func (s *visitorState) validate() error {
       
  1281 	if !s.active {
       
  1282 		return nil
       
  1283 	}
       
  1284 	undecoded := make([]string, 0, len(s.keys))
       
  1285 	for key := range s.keys {
       
  1286 		undecoded = append(undecoded, key)
       
  1287 	}
       
  1288 	sort.Strings(undecoded)
       
  1289 	if len(undecoded) > 0 {
       
  1290 		return fmt.Errorf("undecoded keys: %q", undecoded)
       
  1291 	}
       
  1292 	return nil
       
  1293 }
       
  1294 
       
  1295 func insertKeys(path []string, m map[string]struct{}, tree *Tree) {
       
  1296 	for k, v := range tree.values {
       
  1297 		switch node := v.(type) {
       
  1298 		case []*Tree:
       
  1299 			for i, item := range node {
       
  1300 				insertKeys(append(path, k, strconv.Itoa(i)), m, item)
       
  1301 			}
       
  1302 		case *Tree:
       
  1303 			insertKeys(append(path, k), m, node)
       
  1304 		case *tomlValue:
       
  1305 			m[strings.Join(append(path, k), ".")] = struct{}{}
       
  1306 		}
       
  1307 	}
       
  1308 }