From d305305fabb3245903d8754ae463a99be8dd024b Mon Sep 17 00:00:00 2001 From: Matthew Rich Date: Mon, 25 Aug 2025 03:56:56 +0000 Subject: [PATCH] add ref interfaces --- internal/folio/referrer.go | 133 +++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 internal/folio/referrer.go diff --git a/internal/folio/referrer.go b/internal/folio/referrer.go new file mode 100644 index 0000000..161732e --- /dev/null +++ b/internal/folio/referrer.go @@ -0,0 +1,133 @@ +// Copyright 2024 Matthew Rich . All rights reserved. + +package folio + +import ( + "encoding/json" + "gopkg.in/yaml.v3" + "net/url" + "decl/internal/data" + "decl/internal/mapper" + "errors" +) + +var ( +// ErrInvalidURI error = errors.New("Invalid URI") + ErrInvalidReferenceType error = errors.New("invalid ReferenceType value") +) + +type ReferenceTypes interface { + *Document | *Declaration +} + +type RefMap[T ReferenceTypes] mapper.Store[string, T] + +type ReferenceMapper[T ReferenceTypes] interface { + mapper.Map[URI, T] +} +type ResourceMapper ReferenceMapper[*Declaration] +type DocumentMapper ReferenceMapper[*Document] + +type ReferenceType string +type RefType[T ReferenceTypes, TypedReferenceMapper ReferenceMapper[T]] ReferenceType + +type ReferenceURI[T ReferenceTypes] URI +type DocumentURI ReferenceURI[*Document] +type ResourceURI ReferenceURI[*Declaration] + +const ( + ReferenceTypeResource ReferenceType = "resource" + RefTypeResource RefType[*Declaration, mapper.Store[URI, *Declaration]] = RefType[*Declaration, mapper.Store[URI, *Declaration]](ReferenceTypeResource) + ReferenceTypeDocument ReferenceType = "document" + RefTypeDocument RefType[*Document, mapper.Store[URI, *Document]] = RefType[*Document, mapper.Store[URI, *Document]](ReferenceTypeDocument) +) + +type CommonReferrer interface { + ReferenceType() ReferenceType + Parse() *url.URL + Exists() bool + data.ContentReadWriter + IsEmpty() bool +} + +// interface for a reference +type Referrer[T ReferenceTypes, TypedReferenceMapper ReferenceMapper[T]] interface { + CommonReferrer + Lookup(TypedReferenceMapper) ContentReadWriter + GetContentReadWriter(TypedReferenceMapper) ContentReadWriter + Dereference(TypedReferenceMapper) T +} + +/* +func (r ReferenceType) URIType() any { + switch r { + case ReferenceTypeDocument: + return ReferenceURI[*Document] + case ReferenceTypeResource: + return ReferenceURI[*Declaration] + } +} +*/ + +func (r *RefType[T, TypedReferenceMapper]) UnmarshalValue(value string) error { + switch value { + case string(ReferenceTypeResource), string(ReferenceTypeDocument): + *r = RefType[T, TypedReferenceMapper](value) + return nil + default: + return ErrInvalidReferenceType + } +} + +func (r *RefType[T, TypedReferenceMapper]) UnmarshalJSON(data []byte) error { + var s string + if unmarshalReferenceTypeErr := json.Unmarshal(data, &s); unmarshalReferenceTypeErr != nil { + return unmarshalReferenceTypeErr + } + return r.UnmarshalValue(s) +} + +func (r *RefType[T, TypedReferenceMapper]) UnmarshalYAML(value *yaml.Node) error { + var s string + if err := value.Decode(&s); err != nil { + return err + } + return r.UnmarshalValue(s) +} + +func (r *RefType[T, TypedReferenceMapper]) Dereference(uri URI, look TypedReferenceMapper) (result T) { + result = nil + if uri != "" { + if v,ok := look.Get(uri); ok { + result = v + } + } + return +} + +func RefURI[T ReferenceTypes, RT RefType[T, ReferenceMapper[T]], RU ReferenceURI[T]](uri URI, reftype RT) (refuri RU) { + refuri = RU(uri) + return +} + +/* +func (r *ReferenceURI[T]) GetContentReadWriter(mapper TypedReferenceMapper) ContentReadWriter { + if URI(r).String() == "" { + return nil + } + if mapper != nil { + if v,ok := mapper.Get(string(r)); ok { + return v.(data.Originator).GetContentReadWriter() + } + } + return r +} +*/ + +type ResourceMapSetter interface { + SetResourceMapper(ResourceMapper) +} + +func NewResourceMapper() ResourceMapper { + return mapper.New[URI, *Declaration]() +}