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(asset coindesk.Asset) (data Asset) { data, ok := r.Assets[asset] if !ok { data = r.Defaults } if data.Asset == "" { data.Asset = asset } if data.Goals == nil || len(data.Goals) == 0 { data.Goals = r.Defaults.Goals } if data.ConstantBases == nil || len(data.ConstantBases) == 0 { data.ConstantBases = r.Defaults.ConstantBases } if data.RelativeBases == nil || len(data.RelativeBases) == 0 { data.RelativeBases = r.Defaults.RelativeBases } return } // 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) } }