// Copyright 2024 Matthew Rich . All rights reserved. package config import ( "context" "encoding/json" "fmt" "io" "gopkg.in/yaml.v3" "log/slog" "decl/internal/codec" ) type BlockType struct { Name string `json:"name" yaml:"name"` Type TypeName `json:"type" yaml:"type"` } type Block struct { Name string `json:"name" yaml:"name"` Type TypeName `json:"type" yaml:"type"` Values Configuration `json:"values" yaml:"values"` } func NewBlock() *Block { return &Block{ Type: "generic" } } func (b *Block) Clone() *Block { return &Block { Type: b.Type, Values: b.Values.Clone(), } } func (b *Block) Load(r io.Reader) error { return codec.NewYAMLDecoder(r).Decode(b) } func (b *Block) LoadBlock(yamlBlock string) (err error) { err = codec.NewYAMLStringDecoder(yamlBlock).Decode(b) slog.Info("LoadBlock()", "yaml", yamlBlock, "object", b, "err", err) return } func (b *Block) NewConfiguration() error { uri := fmt.Sprintf("%s://", b.Type) newConfig, err := ConfigTypes.New(uri) b.Values = newConfig return err } func (b *Block) GetValue(key string) (any, error) { return b.Values.GetValue(key) } func (b *Block) Configuration() Configuration { return b.Values } func (b *Block) SetURI(uri string) (e error) { b.Values = NewConfiguration(uri) if b.Values == nil { return ErrUnknownConfigurationType } b.Type = TypeName(b.Values.Type()) _,e = b.Values.Read(context.Background()) return e } func (b *Block) UnmarshalValue(value *BlockType) error { b.Name = value.Name if value.Type == "" { b.Type = "generic" } else { b.Type = value.Type } newConfig, configErr := ConfigTypes.New(fmt.Sprintf("%s://", b.Type)) if configErr != nil { return configErr } b.Values = newConfig return nil } func (b *Block) UnmarshalYAML(value *yaml.Node) error { t := &BlockType{} if unmarshalConfigurationTypeErr := value.Decode(t); unmarshalConfigurationTypeErr != nil { return unmarshalConfigurationTypeErr } if err := b.UnmarshalValue(t); err != nil { return err } configurationVals := struct { Values yaml.Node `json:"values"` }{} if unmarshalValuesErr := value.Decode(&configurationVals); unmarshalValuesErr != nil { return unmarshalValuesErr } if unmarshalConfigurationErr := configurationVals.Values.Decode(b.Values); unmarshalConfigurationErr != nil { return unmarshalConfigurationErr } _, readErr := b.Values.Read(context.Background()) return readErr } func (b *Block) UnmarshalJSON(data []byte) error { t := &BlockType{} if unmarshalConfigurationTypeErr := json.Unmarshal(data, t); unmarshalConfigurationTypeErr != nil { return unmarshalConfigurationTypeErr } if err := b.UnmarshalValue(t); err != nil { return err } configurationVals := struct { Values Configuration `json:"values"` }{Values: b.Values} if unmarshalValuesErr := json.Unmarshal(data, &configurationVals); unmarshalValuesErr != nil { return unmarshalValuesErr } _, readErr := b.Values.Read(context.Background()) return readErr } func (b *Block) MarshalYAML() (any, error) { return b, nil }