Stuff
This commit is contained in:
parent
8ad4e70623
commit
a4b74992c4
39
README.md
39
README.md
|
@ -31,14 +31,12 @@ import "github.com/localhots/gobelt/filecache"
|
||||||
|
|
||||||
```go
|
```go
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
var val int
|
var items []Item
|
||||||
filecache.Load(&val, "tmp/cache/items.json", func() interface{} {
|
filecache.Load(&items, "tmp/cache/items.json", func() {
|
||||||
var items []Item
|
|
||||||
err := conn.Query(ctx, "SELECT * FROM items").Load(&items).Error()
|
err := conn.Query(ctx, "SELECT * FROM items").Load(&items).Error()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to load items: %v", err)
|
log.Fatalf("Failed to load items: %v", err)
|
||||||
}
|
}
|
||||||
return items
|
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -83,6 +81,37 @@ s := setstring.New("one", "two")
|
||||||
s.Add("three")
|
s.Add("three")
|
||||||
s.Remove("one", "two").Add("four", "five")
|
s.Remove("one", "two").Add("four", "five")
|
||||||
fmt.Println("Size:", s.Len()) // 3
|
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]
|
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")
|
||||||
|
}
|
||||||
|
```
|
|
@ -1 +1,34 @@
|
||||||
package config
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
[numbers]
|
||||||
|
ary = [1, 2, 3]
|
||||||
|
i = 123
|
||||||
|
|
||||||
|
[words]
|
||||||
|
foo = "bar"
|
||||||
|
[words.list]
|
||||||
|
foo = ["buzz", "fizz"]
|
|
@ -4,18 +4,15 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Load will look for a given file. If it exists, it would unmarshal its
|
// 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
|
// 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.
|
// 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)
|
_, err := os.Stat(filename)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
out := fn()
|
fn()
|
||||||
reflect.ValueOf(val).Elem().Set(reflect.ValueOf(out))
|
|
||||||
|
|
||||||
body, err := json.Marshal(val)
|
body, err := json.Marshal(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -12,9 +12,9 @@ func TestFileCache(t *testing.T) {
|
||||||
var res int
|
var res int
|
||||||
var nCalled int
|
var nCalled int
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
err := Load(&res, filename, func() interface{} {
|
err := Load(&res, filename, func() {
|
||||||
nCalled++
|
nCalled++
|
||||||
return exp
|
res = exp
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error occurred while loading cache: %v", err)
|
t.Fatalf("Error occurred while loading cache: %v", err)
|
||||||
|
|
Loading…
Reference in New Issue