1
0
Fork 0
secondly/confection.go

77 lines
1.6 KiB
Go

package confection2
import (
"encoding/json"
"log"
"reflect"
)
var (
// config stores application config.
config interface{}
callbacks = make(map[string][]func(oldVal, newVal interface{}))
)
// Manage accepts a pointer to a configuration struct.
func Manage(target interface{}) {
if ok := isStructPtr(target); !ok {
panic("Argument must be a pointer to a struct")
}
config = target
}
// OnChange adds a callback function that is triggered every time a value of
// a field changes.
func OnChange(field string, fun func(oldVal, newVal interface{})) {
callbacks[field] = append(callbacks[field], fun)
}
func update(body []byte) {
dupe := duplicate(config)
if err := unmarshal(body, dupe); err != nil {
log.Println("Failed to update config")
return
}
defer triggerCallbacks(config, dupe)
// Setting new config
config = dupe
}
func triggerCallbacks(oldConf, newConf interface{}) {
return
}
func isStructPtr(target interface{}) bool {
if val := reflect.ValueOf(target); val.Kind() == reflect.Ptr {
if val = reflect.Indirect(val); val.Kind() == reflect.Struct {
return true
}
}
return false
}
func unmarshal(body []byte, target interface{}) error {
if err := json.Unmarshal(body, target); err != nil {
return err
}
return nil
}
func duplicate(original interface{}) interface{} {
// Get the interface value
val := reflect.ValueOf(original)
// We expect a pointer to a struct, so now we need the underlying staruct
val = reflect.Indirect(val)
// Now we need the type (name) of this struct
typ := val.Type()
// Creating a duplicate instance of that struct
dupe := reflect.New(typ).Interface()
return dupe
}