func (m *Map) Clone() Map {
	cloned := make(map[string]string, len(m.values))
	for k, v := range m.values {
		cloned[k] = v
	}
	return Map{
		populated: m.populated,
		schema:    m.schema,
		values:    cloned,
	}
}
Clone the existing map
package config
import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"github.com/pkg/errors"
)
type Map struct {
	schema    Schema
	values    map[string]string
	populated bool
}
func New(schema Schema, values map[string]string) (Map, error) {
	m := Map{
		schema: schema,
		values: make(map[string]string),
	}
	_, err := m.update(values)
	return m, err
}
func (m *Map) Change(changes map[string]interface{}) (map[string]string, error) {
	values := make(map[string]string, len(m.schema))
	var errs ErrorList
	for name, change := range changes {
		key, ok := m.schema[name]
		if ok && key.Hidden && change == true {
			var err error
			if change, err = m.GetRaw(name); err != nil {
				errs.Add(name, nil, err.Error())
				continue
			}
		}
		if change == nil {
			change = ""
		}
		switch v := change.(type) {
		case string:
			values[name] = v
		default:
			errs.Add(name, nil, fmt.Sprintf("invalid type %T", v))
		}
	}
	for name, key := range m.schema {
		if _, ok := values[name]; !ok {
			values[name] = key.Default
		}
	}
	if errs.Len() > 0 {
		return nil, errs
	}
	names, err := m.update(values)
	changed := make(map[string]string)
	for _, name := range names {
		changed[name], err = m.GetRaw(name)
		if err != nil {
			return nil, errors.WithStack(err)
		}
	}
	return changed, errors.WithStack(err)
}
func (m *Map) Dump() (map[string]interface{}, error) {
	values := make(map[string]interface{})
	for name, key := range m.schema {
		value, err := m.GetRaw(name)
		if err != nil {
			return nil, errors.WithStack(err)
		}
		if value != key.Default {
			if key.Hidden {
				values[name] = true
			} else {
				values[name] = value
			}
		}
	}
	return values, nil
}
func (m *Map) GetRaw(name string) (string, error) {
	key, err := m.schema.getKey(name)
	if err != nil {
		return "", errors.WithStack(err)
	}
	value, ok := m.values[name]
	if !ok {
		value = key.Default
	}
	return value, nil
}
func (m *Map) GetString(name string) (string, error) {
	if err := m.schema.assertKeyType(name, String); err != nil {
		return "", errors.WithStack(err)
	}
	return m.GetRaw(name)
}
func (m *Map) GetBool(name string) (bool, error) {
	if err := m.schema.assertKeyType(name, Bool); err != nil {
		return false, errors.WithStack(err)
	}
	raw, err := m.GetRaw(name)
	if err != nil {
		return false, errors.WithStack(err)
	}
	return contains(strings.ToLower(raw), truthy), nil
}
func (m *Map) GetInt64(name string) (int64, error) {
	if err := m.schema.assertKeyType(name, Int64); err != nil {
		return -1, errors.WithStack(err)
	}
	raw, err := m.GetRaw(name)
	if err != nil {
		return -1, errors.WithStack(err)
	}
	n, err := strconv.ParseInt(raw, 10, 64)
	if err != nil {
		return -1, errors.Wrap(err, "cannot convert to int64")
	}
	return n, nil
}