1
0
Fork 0
This commit is contained in:
Gregory Eremin 2018-06-24 16:36:44 +02:00
parent 8ad4e70623
commit a4b74992c4
No known key found for this signature in database
GPG Key ID: 8CB79D42167BEB7F
6 changed files with 127 additions and 12 deletions

View File

@ -31,14 +31,12 @@ import "github.com/localhots/gobelt/filecache"
```go
ctx := context.Background()
var val int
filecache.Load(&val, "tmp/cache/items.json", func() interface{} {
var items []Item
filecache.Load(&items, "tmp/cache/items.json", func() {
err := conn.Query(ctx, "SELECT * FROM items").Load(&items).Error()
if err != nil {
log.Fatalf("Failed to load items: %v", err)
}
return items
})
```
@ -83,6 +81,37 @@ s := setstring.New("one", "two")
s.Add("three")
s.Remove("one", "two").Add("four", "five")
fmt.Println("Size:", s.Len()) // 3
fmt.Println("Has one", s.Has("one"))
fmt.Println("Has one", s.Has("one")) // false
fmt.Println(s.SortedSlice()) // [three four five]
```
### Config
```go
import "github.com/localhots/gobelt/config"
```
Describe configuration structure inside a target package.
```go
package db
var conf struct {
Flavor string `toml:"flavor"`
DSN string `toml:"dsn"`
}
func init() {
config.Require("db", &conf)
}
```
Load configuration from a `main` function:
```go
package main
func main() {
config.Load("config/config.toml")
}
```

View File

@ -1 +1,34 @@
package config
import (
"github.com/BurntSushi/toml"
)
var configs = map[string]interface{}{}
// Require registers a request for package configuration.
func Require(key string, dest interface{}) {
configs[key] = dest
}
// Load reads the config file and distributes provided configuration to
// requested destinations.
func Load(path string) error {
var conf map[string]toml.Primitive
meta, err := toml.DecodeFile(path, &conf)
if err != nil {
return err
}
for key, prim := range conf {
dest, ok := configs[key]
if !ok {
continue
}
err := meta.PrimitiveDecode(prim, dest)
if err != nil {
return err
}
}
return nil
}

48
config/config_test.go Normal file
View File

@ -0,0 +1,48 @@
package config
import (
"testing"
"github.com/google/go-cmp/cmp"
)
func TestConfig(t *testing.T) {
type numbers struct {
Ary []int `toml:"ary"`
I int `toml:"i"`
}
var nums numbers
Require("numbers", &nums)
numsExp := numbers{
Ary: []int{1, 2, 3},
I: 123,
}
type words struct {
Foo string `toml:"foo"`
List struct {
Foo []string `toml:"foo"`
} `toml:"list"`
}
var w words
Require("words", &w)
wordsExp := words{
Foo: "bar",
List: struct {
Foo []string `toml:"foo"`
}{
Foo: []string{"buzz", "fizz"},
},
}
err := Load("example.toml")
if err != nil {
t.Fatalf("Failed to load config: %v", err)
}
if !cmp.Equal(numsExp, nums) {
t.Errorf("Numbers mismatch: %s", cmp.Diff(numsExp, nums))
}
if !cmp.Equal(wordsExp, w) {
t.Errorf("Words mismatch: %s", cmp.Diff(wordsExp, w))
}
}

8
config/example.toml Normal file
View File

@ -0,0 +1,8 @@
[numbers]
ary = [1, 2, 3]
i = 123
[words]
foo = "bar"
[words.list]
foo = ["buzz", "fizz"]

View File

@ -4,18 +4,15 @@ import (
"encoding/json"
"io/ioutil"
"os"
"reflect"
)
// Load will look for a given file. If it exists, it would unmarshal its
// contents into the given value. If the file does not exist, a supplied
// function would be called and its output would be written to a file.
func Load(val interface{}, filename string, fn func() interface{}) error {
func Load(val interface{}, filename string, fn func()) error {
_, err := os.Stat(filename)
if os.IsNotExist(err) {
out := fn()
reflect.ValueOf(val).Elem().Set(reflect.ValueOf(out))
fn()
body, err := json.Marshal(val)
if err != nil {
return err

View File

@ -12,9 +12,9 @@ func TestFileCache(t *testing.T) {
var res int
var nCalled int
for i := 0; i < 10; i++ {
err := Load(&res, filename, func() interface{} {
err := Load(&res, filename, func() {
nCalled++
return exp
res = exp
})
if err != nil {
t.Fatalf("Error occurred while loading cache: %v", err)