jx/internal/folio/block.go
Matthew Rich 6e0049c4d2
Some checks are pending
Lint / golangci-lint (push) Waiting to run
Declarative Tests / test (push) Waiting to run
Declarative Tests / build-fedora (push) Waiting to run
Declarative Tests / build-ubuntu-focal (push) Waiting to run
add resource and document constraints
2024-09-19 07:57:26 +00:00

219 lines
5.4 KiB
Go

// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
package folio
import (
"context"
"encoding/json"
"fmt"
"io"
"net/url"
"strings"
"gopkg.in/yaml.v3"
"decl/internal/codec"
"decl/internal/data"
"decl/internal/schema"
)
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 data.Configuration `json:"values" yaml:"values"`
ConfigurationTypes data.TypesRegistry[data.Configuration] `json:"-" yaml:"-"`
}
func NewBlock() *Block {
return &Block{ Type: "generic", ConfigurationTypes: DocumentRegistry.ConfigurationTypes }
}
func (b *Block) Clone() data.Block {
return &Block {
Type: b.Type,
Values: b.Values.Clone(),
}
}
func (b *Block) Load(docData []byte, f codec.Format) (err error) {
err = f.StringDecoder(string(docData)).Decode(b)
return
}
func (b *Block) LoadReader(r io.ReadCloser, f codec.Format) (err error) {
err = f.Decoder(r).Decode(b)
return
}
func (b *Block) LoadString(docData string, f codec.Format) (err error) {
err = f.StringDecoder(docData).Decode(b)
return
}
func (b *Block) LoadBlock(yamlBlock string) (err error) {
return b.LoadString(yamlBlock, codec.FormatYaml)
}
func (b *Block) JSON() ([]byte, error) {
var buf strings.Builder
err := codec.FormatJson.Serialize(b, &buf)
return []byte(buf.String()), err
}
func (b *Block) YAML() ([]byte, error) {
var buf strings.Builder
err := codec.FormatYaml.Serialize(b, &buf)
return []byte(buf.String()), err
}
func (b *Block) PB() ([]byte, error) {
var buf strings.Builder
err := codec.FormatProtoBuf.Serialize(b, &buf)
return []byte(buf.String()), err
}
func (b *Block) Validate() (err error) {
var blockJson []byte
if blockJson, err = b.JSON(); err == nil {
s := schema.New(fmt.Sprintf("%s-block", b.Type), schemaFiles) // XXX wrong schemaFiles
err = s.Validate(string(blockJson))
}
return
}
func (b *Block) NewConfiguration(uri *string) (err error) {
if b.ConfigurationTypes == nil {
panic(fmt.Errorf("Undefined type registry: unable to create new configuration %s", *uri))
}
if uri == nil {
b.Values, err = b.ConfigurationTypes.New(fmt.Sprintf("%s://", b.Type))
} else {
b.Values, err = b.ConfigurationTypes.New(*uri)
}
return
}
func (b *Block) NewConfigurationFromParsedURI(uri *url.URL) (err error) {
if uri == nil {
b.Values, err = b.ConfigurationTypes.New(fmt.Sprintf("%s://", b.Type))
} else {
b.Values, err = b.ConfigurationTypes.NewFromParsedURI(uri)
}
return
}
func (b *Block) GetValue(key string) (any, error) {
return b.Values.GetValue(key)
}
func (b *Block) Configuration() data.Configuration {
return b.Values
}
func (b *Block) ConfigurationType() data.TypeName {
return data.TypeName(b.Type)
}
func (b *Block) URI() string {
return b.Values.URI()
}
func (b *Block) SetURI(uri string) (err error) {
if b.Values == nil {
if err = b.NewConfiguration(&uri); err != nil {
return
}
}
if b.Values == nil {
return fmt.Errorf("%w - %s", data.ErrUnknownConfigurationType, uri)
}
b.Type = TypeName(b.Values.Type())
_,err = b.Values.Read(context.Background())
return
}
func (b *Block) SetParsedURI(uri *url.URL) (err error) {
if b.Values == nil {
if err = b.NewConfigurationFromParsedURI(uri); err != nil {
return
}
}
if b.Values == nil {
return fmt.Errorf("%w - %s", data.ErrUnknownConfigurationType, uri)
}
b.Type = TypeName(b.Values.Type())
_,err = b.Values.Read(context.Background())
return
}
func (b *Block) UnmarshalValue(value *BlockType) error {
if b.ConfigurationTypes == nil {
panic(fmt.Errorf("Undefined type registry: unable to create new configuration %s", value.Type))
}
b.Name = value.Name
if value.Type == "" {
b.Type = "generic"
} else {
b.Type = value.Type
}
newConfig, configErr := b.ConfigurationTypes.New(fmt.Sprintf("%s://", b.Type))
if configErr != nil {
return configErr
}
b.Values = newConfig
return nil
}
func (b *Block) UnmarshalYAML(value *yaml.Node) error {
if b.ConfigurationTypes == nil {
b.ConfigurationTypes = DocumentRegistry.ConfigurationTypes
}
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(jsonData []byte) error {
if b.ConfigurationTypes == nil {
b.ConfigurationTypes = DocumentRegistry.ConfigurationTypes
}
t := &BlockType{}
if unmarshalConfigurationTypeErr := json.Unmarshal(jsonData, t); unmarshalConfigurationTypeErr != nil {
return unmarshalConfigurationTypeErr
}
if err := b.UnmarshalValue(t); err != nil {
return err
}
configurationVals := struct {
Values data.Configuration `json:"values"`
}{Values: b.Values}
if unmarshalValuesErr := json.Unmarshal(jsonData, &configurationVals); unmarshalValuesErr != nil {
return unmarshalValuesErr
}
_, readErr := b.Values.Read(context.Background())
return readErr
}