// Copyright 2024 Matthew Rich . All rights reserved. // The resource package handles CRUD operations on resources and YAML (de)serialization package resource import ( _ "encoding/json" _ "fmt" _ "gopkg.in/yaml.v3" "gitea.rosskeen.house/rosskeen.house/machine" "decl/internal/data" "errors" ) var ( ErrInvalidResourceURI error = errors.New("Invalid resource URI") ErrResourceStateAbsent = errors.New("Resource state absent") ErrUnableToFindResource = errors.New("Unable to find resource - not loaded") ) type ResourceReference string /* type ResourceSelector func(r *Declaration) bool type Resource interface { Type() string StateMachine() machine.Stater URI() string SetURI(string) error UseConfig(config ConfigurationValueGetter) ResolveId(context.Context) string ResourceLoader StateTransformer ResourceReader ResourceValidator Clone() Resource SetResourceMapper(resources ResourceMapper) } type ContentReader interface { ContentReaderStream() (*transport.Reader, error) } type ContentWriter interface { ContentWriterStream() (*transport.Writer, error) } type ContentReadWriter interface { ContentReader ContentWriter } type ResourceValidator interface { Validate() error } type ResourceCreator interface { Create(context.Context) error } type ResourceReader interface { Read(context.Context) ([]byte, error) } type ResourceUpdater interface { Update(context.Context) error } type ResourceDeleter interface { Delete(context.Context) error } type ResourceDecoder struct { } type ResourceCrudder struct { ResourceCreator ResourceReader ResourceUpdater ResourceDeleter } */ func NewResource(uri string) data.Resource { r, e := ResourceTypes.New(uri) if e == nil { return r } return nil } /* // Return a Content ReadWriter for the resource referred to. func (r ResourceReference) Lookup(look data.ResourceMapper) data.ContentReadWriter { slog.Info("ResourceReference.Lookup()", "resourcereference", r, "resourcemapper", look) if look != nil { if v,ok := look.Get(string(r)); ok { return v.(data.ContentReadWriter) } } return r } func (r ResourceReference) Dereference(look data.ResourceMapper) data.Resource { slog.Info("ResourceReference.Dereference()", "resourcereference", r, "resourcemapper", look) if look != nil { if v,ok := look.Get(string(r)); ok { return v.(*Declaration).Attributes } } return nil } func (r ResourceReference) Parse() *url.URL { u, e := url.Parse(string(r)) if e == nil { return u } return nil } func (r ResourceReference) Exists() bool { return transport.ExistsURI(string(r)) } func (r ResourceReference) ContentReaderStream() (*transport.Reader, error) { return transport.NewReaderURI(string(r)) } func (r ResourceReference) ContentWriterStream() (*transport.Writer, error) { return transport.NewWriterURI(string(r)) } */ func StorageMachine(sub machine.Subscriber) machine.Stater { // start_destroy -> absent -> start_create -> present -> start_destroy stater := machine.New("unknown") stater.AddStates("unkonwn", "absent", "start_create", "present", "start_delete", "start_read", "start_update") stater.AddTransition("create", machine.States("unknown", "absent"), "start_create") if e := stater.AddSubscription("create", sub); e != nil { return nil } stater.AddTransition("created", machine.States("start_create"), "present") if e := stater.AddSubscription("created", sub); e != nil { return nil } stater.AddTransition("exists", machine.States("unknown", "absent"), "present") if e := stater.AddSubscription("exists", sub); e != nil { return nil } stater.AddTransition("notexists", machine.States("*"), "absent") if e := stater.AddSubscription("notexists", sub); e != nil { return nil } stater.AddTransition("read", machine.States("*"), "start_read") if e := stater.AddSubscription("read", sub); e != nil { return nil } stater.AddTransition("state_read", machine.States("start_read"), "present") stater.AddTransition("update", machine.States("*"), "start_update") if e := stater.AddSubscription("update", sub); e != nil { return nil } stater.AddTransition("updated", machine.States("start_update"), "present") stater.AddTransition("delete", machine.States("*"), "start_delete") if e := stater.AddSubscription("delete", sub); e != nil { return nil } stater.AddTransition("deleted", machine.States("start_delete"), "absent") if e := stater.AddSubscription("deleted", sub); e != nil { return nil } return stater } func ProcessMachine(sub machine.Subscriber) machine.Stater { // "enum": [ "created", "restarting", "running", "paused", "exited", "dead" ] stater := machine.New("unknown") stater.AddStates("unkonwn", "absent", "start_create", "present", "created", "restarting", "running", "paused", "exited", "dead", "start_delete", "start_read", "start_update") stater.AddTransition("create", machine.States("unknown", "absent"), "start_create") if e := stater.AddSubscription("create", sub); e != nil { return nil } stater.AddTransition("created", machine.States("start_create"), "present") if e := stater.AddSubscription("created", sub); e != nil { return nil } stater.AddTransition("exists", machine.States("unknown", "absent"), "present") if e := stater.AddSubscription("exists", sub); e != nil { return nil } stater.AddTransition("notexists", machine.States("*"), "absent") if e := stater.AddSubscription("notexists", sub); e != nil { return nil } stater.AddTransition("read", machine.States("*"), "start_read") if e := stater.AddSubscription("read", sub); e != nil { return nil } stater.AddTransition("state_read", machine.States("start_read"), "present") stater.AddTransition("update", machine.States("*"), "start_update") if e := stater.AddSubscription("update", sub); e != nil { return nil } stater.AddTransition("updated", machine.States("start_update"), "present") stater.AddTransition("delete", machine.States("*"), "start_delete") if e := stater.AddSubscription("delete", sub); e != nil { return nil } stater.AddTransition("deleted", machine.States("start_delete"), "absent") if e := stater.AddSubscription("deleted", sub); e != nil { return nil } return stater }