func buildPlatformPath(path string) string {
	if runtime.GOOS == "windows" {
		return fmt.Sprintf("%s\\%s\\%s", os.Getenv("APPDATA"),
			applicationName,
			path)
	}
	var unixConfigDir string
	if xdg := os.Getenv("XDG_CONFIG_HOME"); xdg != "" {
		unixConfigDir = xdg
	} else {
		unixConfigDir = os.Getenv("HOME") + "/.config"
	}
	return fmt.Sprintf("%s/%s/%s", unixConfigDir,
		applicationName,
		path)
}
buildPlatformPath builds a platform-dependent path for relative path given.
package store
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"runtime"
	"github.com/BurntSushi/toml"
	"gopkg.in/yaml.v2"
)
type MarshalFunc func(v interface{}) ([]byte, error)
type UnmarshalFunc func(data []byte, v interface{}) error
var (
	applicationName = ""
	formats         = map[string]format{}
)
type format struct {
	m  MarshalFunc
	um UnmarshalFunc
}
func init() {
	formats["json"] = format{m: json.Marshal, um: json.Unmarshal}
	formats["yaml"] = format{m: yaml.Marshal, um: yaml.Unmarshal}
	formats["yml"] = format{m: yaml.Marshal, um: yaml.Unmarshal}
	formats["toml"] = format{
		m: func(v interface{}) ([]byte, error) {
			b := bytes.Buffer{}
			err := toml.NewEncoder(&b).Encode(v)
			return b.Bytes(), err
		},
		um: toml.Unmarshal,
	}
}
func Init(application string) {
	applicationName = application
}
func Register(extension string, m MarshalFunc, um UnmarshalFunc) {
	formats[extension] = format{m, um}
}
func Load(path string, v interface{}) error {
	if applicationName == "" {
		panic("store: application name not defined")
	}
	if format, ok := formats[extension(path)]; ok {
		return LoadWith(path, v, format.um)
	}
	panic("store: unknown configuration format")
}
func Save(path string, v interface{}) error {
	if applicationName == "" {
		panic("store: application name not defined")
	}
	if format, ok := formats[extension(path)]; ok {
		return SaveWith(path, v, format.m)
	}
	panic("store: unknown configuration format")
}
func LoadWith(path string, v interface{}, um UnmarshalFunc) error {
	if applicationName == "" {
		panic("store: application name not defined")
	}
	globalPath := buildPlatformPath(path)
	data, err := ioutil.ReadFile(globalPath)
	if err != nil {
		empty := reflect.New(reflect.TypeOf(v))
		if innerErr := Save(path, &empty); innerErr != nil {
			return err
		}
		v = empty
		return nil
	}
	if err := um(data, v); err != nil {
		return fmt.Errorf("store: failed to unmarshal %s: %v", path, err)
	}
	return nil
}
func SaveWith(path string, v interface{}, m MarshalFunc) error {
	if applicationName == "" {
		panic("store: application name not defined")
	}
	var b bytes.Buffer
	if data, err := m(v); err == nil {
		b.Write(data)
	} else {
		return fmt.Errorf("store: failed to marshal %s: %v", path, err)
	}
	b.WriteRune('\n')
	globalPath := buildPlatformPath(path)
	if err := os.MkdirAll(filepath.Dir(globalPath), os.ModePerm); err != nil {
		return err
	}
	if err := ioutil.WriteFile(globalPath, b.Bytes(), os.ModePerm); err != nil {
		return err
	}
	return nil
}
func extension(path string) string {
	for i := len(path) - 1; i >= 0; i-- {
		if path[i] == '.' {
			return path[i+1:]
		}
	}
	return ""
}