func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error {
	vt := t
	isPtr := t.Kind() == reflect.Ptr
	if isPtr {
		vt = t.Elem()
	}
	switch vt.Kind() {
	case reflect.String:
		stringVal := key.String()
		if isPtr {
			field.Set(reflect.ValueOf(&stringVal))
		} else if len(stringVal) > 0 {
			field.SetString(key.String())
		}
	case reflect.Bool:
		boolVal, err := key.Bool()
		if err != nil {
			return wrapStrictError(err, isStrict)
		}
		if isPtr {
			field.Set(reflect.ValueOf(&boolVal))
		} else {
			field.SetBool(boolVal)
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if vt.Name() == "Duration" {
			durationVal, err := key.Duration()
			if err != nil {
				if intVal, err := key.Int64(); err == nil {
					field.SetInt(intVal)
					return nil
				}
				return wrapStrictError(err, isStrict)
			}
			if isPtr {
				field.Set(reflect.ValueOf(&durationVal))
			} else if int64(durationVal) > 0 {
				field.Set(reflect.ValueOf(durationVal))
			}
			return nil
		}
		intVal, err := key.Int64()
		if err != nil {
			return wrapStrictError(err, isStrict)
		}
		if isPtr {
			pv := reflect.New(t.Elem())
			pv.Elem().SetInt(intVal)
			field.Set(pv)
		} else {
			field.SetInt(intVal)
		}
	case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		durationVal, err := key.Duration()
		if err == nil && uint64(durationVal) > 0 {
			if isPtr {
				field.Set(reflect.ValueOf(&durationVal))
			} else {
				field.Set(reflect.ValueOf(durationVal))
			}
			return nil
		}
		uintVal, err := key.Uint64()
		if err != nil {
			return wrapStrictError(err, isStrict)
		}
		if isPtr {
			pv := reflect.New(t.Elem())
			pv.Elem().SetUint(uintVal)
			field.Set(pv)
		} else {
			field.SetUint(uintVal)
		}
	case reflect.Float32, reflect.Float64:
		floatVal, err := key.Float64()
		if err != nil {
			return wrapStrictError(err, isStrict)
		}
		if isPtr {
			pv := reflect.New(t.Elem())
			pv.Elem().SetFloat(floatVal)
			field.Set(pv)
		} else {
			field.SetFloat(floatVal)
		}
	case reflectTime:
		timeVal, err := key.Time()
		if err != nil {
			return wrapStrictError(err, isStrict)
		}
		if isPtr {
			field.Set(reflect.ValueOf(&timeVal))
		} else {
			field.Set(reflect.ValueOf(timeVal))
		}
	case reflect.Slice:
		return setSliceWithProperType(key, field, delim, allowShadow, isStrict)
	default:
		return fmt.Errorf("unsupported type %q", t)
	}
	return nil
}
setWithProperType sets proper value to field based on its type,
but it does not return error for failing parsing,
because we want to use default value that is already assigned to struct.
package ini
import (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"strings"
	"time"
	"unicode"
)
type NameMapper func(string) string
var (
	SnackCase NameMapper = func(raw string) string {
		newstr := make([]rune, 0, len(raw))
		for i, chr := range raw {
			if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
				if i > 0 {
					newstr = append(newstr, '_')
				}
			}
			newstr = append(newstr, unicode.ToUpper(chr))
		}
		return string(newstr)
	}
	TitleUnderscore NameMapper = func(raw string) string {
		newstr := make([]rune, 0, len(raw))
		for i, chr := range raw {
			if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
				if i > 0 {
					newstr = append(newstr, '_')
				}
				chr -= 'A' - 'a'
			}
			newstr = append(newstr, chr)
		}
		return string(newstr)
	}
)
func (s *Section) parseFieldName(raw, actual string) string {
	if len(actual) > 0 {
		return actual
	}
	if s.f.NameMapper != nil {
		return s.f.NameMapper(raw)
	}
	return raw
}
func parseDelim(actual string) string {
	if len(actual) > 0 {
		return actual
	}
	return ","
}
var reflectTime = reflect.TypeOf(time.Now()).Kind()
func setSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error {
	var strs []string
	if allowShadow {
		strs = key.StringsWithShadows(delim)
	} else {
		strs = key.Strings(delim)
	}
	numVals := len(strs)
	if numVals == 0 {
		return nil
	}
	var vals interface{}
	var err error
	sliceOf := field.Type().Elem().Kind()
	switch sliceOf {
	case reflect.String:
		vals = strs
	case reflect.Int:
		vals, err = key.parseInts(strs, true, false)
	case reflect.Int64:
		vals, err = key.parseInt64s(strs, true, false)
	case reflect.Uint:
		vals, err = key.parseUints(strs, true, false)
	case reflect.Uint64:
		vals, err = key.parseUint64s(strs, true, false)
	case reflect.Float64:
		vals, err = key.parseFloat64s(strs, true, false)
	case reflect.Bool:
		vals, err = key.parseBools(strs, true, false)
	case reflectTime:
		vals, err = key.parseTimesFormat(time.RFC3339, strs, true, false)
	default:
		return fmt.Errorf("unsupported type '[]%s'", sliceOf)
	}
	if err != nil && isStrict {
		return err
	}
	slice := reflect.MakeSlice(field.Type(), numVals, numVals)
	for i := 0; i < numVals; i++ {
		switch sliceOf {
		case reflect.String:
			slice.Index(i).Set(reflect.ValueOf(vals.([]string)[i]))
		case reflect.Int:
			slice.Index(i).Set(reflect.ValueOf(vals.([]int)[i]))
		case reflect.Int64:
			slice.Index(i).Set(reflect.ValueOf(vals.([]int64)[i]))
		case reflect.Uint:
			slice.Index(i).Set(reflect.ValueOf(vals.([]uint)[i]))
		case reflect.Uint64:
			slice.Index(i).Set(reflect.ValueOf(vals.([]uint64)[i]))
		case reflect.Float64:
			slice.Index(i).Set(reflect.ValueOf(vals.([]float64)[i]))
		case reflect.Bool:
			slice.Index(i).Set(reflect.ValueOf(vals.([]bool)[i]))
		case reflectTime:
			slice.Index(i).Set(reflect.ValueOf(vals.([]time.Time)[i]))
		}
	}
	field.Set(slice)
	return nil
}
func wrapStrictError(err error, isStrict bool) error {
	if isStrict {
		return err
	}
	return nil
}