108 lines
2.2 KiB
Go
108 lines
2.2 KiB
Go
package config
|
|
|
|
import (
|
|
_ "embed"
|
|
"slices"
|
|
"time"
|
|
|
|
"code.humancabbage.net/sam/moonmath/coindesk"
|
|
"code.humancabbage.net/sam/moonmath/moon"
|
|
"github.com/knadh/koanf/parsers/yaml"
|
|
"github.com/knadh/koanf/providers/file"
|
|
"github.com/knadh/koanf/providers/rawbytes"
|
|
"github.com/knadh/koanf/providers/structs"
|
|
"github.com/knadh/koanf/v2"
|
|
)
|
|
|
|
var k = koanf.New(".")
|
|
|
|
func Load(filePath string) (r Root, err error) {
|
|
err = k.Load(structs.Provider(Default, "koanf"), nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if filePath != "" {
|
|
err = k.Load(file.Provider(filePath), yaml.Parser())
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
err = k.Unmarshal("", &r)
|
|
|
|
return
|
|
}
|
|
|
|
var Default Root
|
|
|
|
type Root struct {
|
|
Defaults Asset `koanf:"defaults"`
|
|
Assets map[coindesk.Asset]Asset `koanf:"assets"`
|
|
}
|
|
|
|
type Asset struct {
|
|
Asset coindesk.Asset `koanf:"asset"`
|
|
Goals []moon.Goal `koanf:"goals"`
|
|
ConstantBases []moon.ConstantBase `koanf:"constantBases"`
|
|
RelativeBases []moon.RelativeBase `koanf:"relativeBases"`
|
|
}
|
|
|
|
func (r Root) ForAsset(a coindesk.Asset) (cfg Asset) {
|
|
cfg = merge(r.Assets[a], r.Defaults)
|
|
cfg.Asset = a
|
|
return
|
|
}
|
|
|
|
func merge(dst, src Asset) Asset {
|
|
if len(dst.Goals) == 0 {
|
|
dst.Goals = src.Goals
|
|
}
|
|
if len(dst.ConstantBases) == 0 {
|
|
dst.ConstantBases = src.ConstantBases
|
|
}
|
|
if len(dst.RelativeBases) == 0 {
|
|
dst.RelativeBases = src.RelativeBases
|
|
}
|
|
return dst
|
|
}
|
|
|
|
// GetBases returns the concatenation of the constant and relative bases, sorted
|
|
// from most recent to least recent in time.
|
|
func GetBases(d *Asset) (bases []moon.Base) {
|
|
for _, b := range d.ConstantBases {
|
|
bases = append(bases, b)
|
|
}
|
|
for _, b := range d.RelativeBases {
|
|
bases = append(bases, b)
|
|
}
|
|
now := time.Now()
|
|
slices.SortFunc(bases, func(a, b moon.Base) int {
|
|
aTime := a.From(now)
|
|
bTime := b.From(now)
|
|
aFirst := aTime.Before(bTime)
|
|
bFirst := bTime.Before(aTime)
|
|
switch {
|
|
case aFirst:
|
|
return 1
|
|
case bFirst:
|
|
return -1
|
|
}
|
|
return 0
|
|
})
|
|
return
|
|
}
|
|
|
|
//go:embed default.yaml
|
|
var defaultYamlBytes []byte
|
|
|
|
func init() {
|
|
var k = koanf.New(".")
|
|
err := k.Load(rawbytes.Provider(defaultYamlBytes), yaml.Parser())
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
err = k.Unmarshal("", &Default)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|