134 lines
3.3 KiB
Go
134 lines
3.3 KiB
Go
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. 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]()
|
|
}
|