2024-03-20 04:44:11 +00:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
2024-03-22 00:39:10 +00:00
|
|
|
_ "embed"
|
2024-03-20 04:44:11 +00:00
|
|
|
"slices"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"code.humancabbage.net/sam/moonmath/coindesk"
|
|
|
|
"code.humancabbage.net/sam/moonmath/moon"
|
2024-03-22 00:39:10 +00:00
|
|
|
"github.com/knadh/koanf/parsers/yaml"
|
2024-03-20 04:44:11 +00:00
|
|
|
"github.com/knadh/koanf/providers/file"
|
2024-03-22 00:39:10 +00:00
|
|
|
"github.com/knadh/koanf/providers/rawbytes"
|
2024-03-20 04:44:11 +00:00
|
|
|
"github.com/knadh/koanf/providers/structs"
|
|
|
|
"github.com/knadh/koanf/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
var k = koanf.New(".")
|
|
|
|
|
2024-03-22 00:39:10 +00:00
|
|
|
func Load(path string) (all All, err error) {
|
2024-03-20 04:44:11 +00:00
|
|
|
err = k.Load(structs.Provider(Default, "koanf"), nil)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if path != "" {
|
2024-03-22 00:39:10 +00:00
|
|
|
err = k.Load(file.Provider(path), yaml.Parser())
|
2024-03-20 04:44:11 +00:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2024-03-22 00:39:10 +00:00
|
|
|
err = k.Unmarshal("", &all)
|
2024-03-20 04:44:11 +00:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-03-22 00:39:10 +00:00
|
|
|
var Default All
|
|
|
|
|
|
|
|
type All struct {
|
|
|
|
Defaults Data `koanf:"defaults"`
|
|
|
|
Assets map[coindesk.Asset]Data `koanf:"assets"`
|
2024-03-20 04:44:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type Data struct {
|
|
|
|
Asset coindesk.Asset `koanf:"asset"`
|
|
|
|
Goals []moon.Goal `koanf:"goals"`
|
|
|
|
ConstantBases []moon.ConstantBase `koanf:"constantBases"`
|
|
|
|
RelativeBases []moon.RelativeBase `koanf:"relativeBases"`
|
|
|
|
}
|
|
|
|
|
2024-03-22 00:39:10 +00:00
|
|
|
func (all All) GetData(asset coindesk.Asset) (data Data, err error) {
|
|
|
|
data, ok := all.Assets[asset]
|
|
|
|
if !ok {
|
|
|
|
data = all.Defaults
|
|
|
|
}
|
|
|
|
if data.Asset == "" {
|
|
|
|
data.Asset = asset
|
|
|
|
}
|
|
|
|
if data.Goals == nil || len(data.Goals) == 0 {
|
|
|
|
data.Goals = all.Defaults.Goals
|
|
|
|
}
|
|
|
|
if data.ConstantBases == nil || len(data.ConstantBases) == 0 {
|
|
|
|
data.ConstantBases = all.Defaults.ConstantBases
|
|
|
|
}
|
|
|
|
if data.RelativeBases == nil || len(data.RelativeBases) == 0 {
|
|
|
|
data.RelativeBases = all.Defaults.RelativeBases
|
|
|
|
}
|
|
|
|
return
|
2024-03-20 04:44:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetBases returns the concatenation of the constant and relative bases, sorted
|
|
|
|
// from most recent to least recent in time.
|
|
|
|
func GetBases(d *Data) (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
|
|
|
|
}
|
2024-03-22 00:39:10 +00:00
|
|
|
|
|
|
|
//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)
|
|
|
|
}
|
|
|
|
}
|