mirror of
https://github.com/xaionaro-go/streamctl.git
synced 2025-10-17 21:11:24 +08:00
Initial commit, part 1
This commit is contained in:
103
pkg/streamcontrol/config.go
Normal file
103
pkg/streamcontrol/config.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package streamctl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/facebookincubator/go-belt/tool/logger"
|
||||
"github.com/goccy/go-yaml"
|
||||
)
|
||||
|
||||
type PlatformConfig[T any, S StreamProfile] struct {
|
||||
Config T
|
||||
StreamProfiles map[string]S
|
||||
}
|
||||
|
||||
type AbstractPlatformConfig = PlatformConfig[any, StreamProfile]
|
||||
|
||||
type Config map[string]*AbstractPlatformConfig
|
||||
|
||||
func (cfg *Config) UnmarshalYAML(b []byte) error {
|
||||
t := map[string]*AbstractPlatformConfig{}
|
||||
err := yaml.Unmarshal(b, &t)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to unmarshal YAML of the root of the config: %w", err)
|
||||
}
|
||||
|
||||
for k, v := range t {
|
||||
b, err := yaml.Marshal(v.Config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to re-marshal YAML of config %#+v: %w", v, err)
|
||||
}
|
||||
|
||||
vOrig, ok := (*cfg)[k]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
cfgCfg := vOrig.Config
|
||||
|
||||
err = yaml.Unmarshal(b, cfgCfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to unmarshal YAML of platform-config %s: %w", b, err)
|
||||
}
|
||||
(*cfg)[k].Config = cfgCfg
|
||||
}
|
||||
|
||||
for k := range *cfg {
|
||||
_, ok := t[k]
|
||||
if !ok {
|
||||
delete(*cfg, k)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetPlatformConfig[T any, S any](ctx context.Context, cfg Config, id string) *PlatformConfig[T, S] {
|
||||
platCfg, ok := cfg[id]
|
||||
if !ok {
|
||||
logger.Debugf(ctx, "config '%s' was not found in cfg: %#+v", id, cfg)
|
||||
return nil
|
||||
}
|
||||
platCfgCfg, ok := platCfg.Config.(*T)
|
||||
if !ok {
|
||||
var zeroValue T
|
||||
logger.Errorf(ctx, "unable to get the config: expected type '%T', but received type '%T'", zeroValue, platCfg.Config)
|
||||
return nil
|
||||
}
|
||||
return &PlatformConfig[T, S]{
|
||||
Config: *platCfgCfg,
|
||||
StreamProfiles: GetStreamProfiles[S](platCfg.StreamProfiles),
|
||||
}
|
||||
}
|
||||
|
||||
func GetStreamProfiles[S any](streamProfiles map[string]StreamProfile) map[string]S {
|
||||
s := make(map[string]S, len(streamProfiles))
|
||||
for k, pI := range streamProfiles {
|
||||
p, ok := pI.(S)
|
||||
if !ok {
|
||||
var zeroS S
|
||||
panic(fmt.Errorf("expected type %T, but received type %T", zeroS, pI))
|
||||
}
|
||||
s[k] = p
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func InitConfig[T any, S any](cfg Config, id string, platCfg PlatformConfig[T, S]) {
|
||||
if _, ok := cfg[id]; ok {
|
||||
panic(fmt.Errorf("id '%s' is already registered", id))
|
||||
}
|
||||
cfg[id] = &PlatformConfig[any, StreamProfile]{
|
||||
Config: &platCfg.Config,
|
||||
}
|
||||
}
|
||||
|
||||
func ToAbstractStreamProfiles[S StreamProfile](in map[string]S) map[string]StreamProfile {
|
||||
m := make(map[string]StreamProfile, len(in))
|
||||
for k, v := range in {
|
||||
m[k] = v
|
||||
}
|
||||
return m
|
||||
}
|
Reference in New Issue
Block a user