package main

import (
	"testing"

	bs_toml "github.com/BurntSushi/toml"
	k_toml "github.com/kezhuw/toml"
	n_toml "github.com/naoina/toml"
	p_toml "github.com/pelletier/go-toml"

	yaml "gopkg.in/yaml.v2"
)

type PersonAddress struct {
	Zip string
}

type Person struct {
	Name    string
	Age     int
	Address []PersonAddress
}

type Data struct {
	Person Person
}

const TomlExample = `
# some comment
[Person]
Name = "One"
Age = 25

  [[Person.Address]]
  Zip = "654321"

  [[Person.Address]]
  Zip = "123456"
`

const YamlExample = `
# some comment
person:
  name: One
  age: 25
  address: &default_address
    -
      zip: 654321
    -
      zip: 123456
`

func do(b *testing.B, f func(*Data) error) {
	for i := 0; i < b.N; i++ {
		d := &Data{}
		if err := f(d); err != nil {
			b.Fatalf("Error is %s", err)
		}
		if d.Person.Name != "One" {
			b.Fatalf("wrong name %s", d.Person.Name)
		}
		if d.Person.Address[0].Zip != "654321" {
			b.Fatalf("wrong zip code")
		}
	}

}

func BenchmarkTomlBurntSushi(b *testing.B) {
	do(b, func(d *Data) error {
		_, err := bs_toml.Decode(TomlExample, d)
		return err
	})
}

func BenchmarkTomlPelletier(b *testing.B) {
	do(b, func(d *Data) error {
		return p_toml.Unmarshal([]byte(TomlExample), d)
	})
}

func BenchmarkTomlNaoina(b *testing.B) {
	do(b, func(d *Data) error {
		return n_toml.Unmarshal([]byte(TomlExample), d)
	})
}

func BenchmarkTomlKezhuw(b *testing.B) {
	do(b, func(d *Data) error {
		return k_toml.Unmarshal([]byte(TomlExample), d)
	})
}

func BenchmarkYaml(b *testing.B) {
	do(b, func(d *Data) error {
		return yaml.Unmarshal([]byte(YamlExample), d)
	})
}

/*
Output:

$ go test -benchmem -run=^$ -bench . go_yaml_toml_bench.go                                                                                                 ~/tmp/y @Igors-MacBook-Pro 21:04
goos: darwin
goarch: amd64
BenchmarkTomlBurntSushi-4   	   30000	     55008 ns/op	    6096 B/op	     145 allocs/op
BenchmarkTomlPelletier-4    	   30000	     63452 ns/op	   17976 B/op	     227 allocs/op
BenchmarkTomlNaoina-4       	   10000	    143479 ns/op	  403337 B/op	     169 allocs/op
BenchmarkTomlKezhuw-4       	  100000	     19914 ns/op	    2664 B/op	      51 allocs/op
BenchmarkYaml-4             	   30000	     46817 ns/op	    8880 B/op	     100 allocs/op
PASS
ok  	command-line-arguments	10.048s
*/