- No more BaseObject with Id and Type included, moved those into the
nsUndefined namespace
- Refactored the full parser funcs into two slightly distinct ones:
  - One that takes in raw bytes and one that takes in a map[string]any
This commit is contained in:
Melody 2024-08-28 19:14:23 +02:00
parent 33a82e544b
commit 2f74543ca1
4 changed files with 107 additions and 68 deletions

View file

@ -16,48 +16,6 @@ type BaseApChain interface {
// It is expected that, on success, the function removes its key from the raw map // It is expected that, on success, the function removes its key from the raw map
type UnmarshalFunc func(map[string]any, BaseApChain) (BaseApChain, error) type UnmarshalFunc func(map[string]any, BaseApChain) (BaseApChain, error)
// The minimum data every AP object has
type BaseObject struct {
Id string
Type string
}
func (b *BaseObject) GetSelfOrBase() (BaseApChain, bool) {
return b, false
}
func (b *BaseObject) MarshalToMap() map[string]any {
return map[string]any{
KEY_ID: b.Id,
KEY_TYPE: b.Type,
}
}
func UnmarshalBaseObject(raw map[string]any, _ BaseApChain) (BaseApChain, error) {
rawId, ok := raw[KEY_ID]
if !ok {
return nil, NoRequiredFieldError{KEY_ID}
}
id, ok := rawId.(string)
if !ok {
return nil, BadFieldValueError[string]{KEY_ID, rawId, ""}
}
rawObjType, ok := raw[KEY_TYPE]
if !ok {
return nil, NoRequiredFieldError{KEY_TYPE}
}
objType, ok := rawObjType.([]string)
if !ok {
return nil, BadFieldValueError[[]string]{KEY_TYPE, rawObjType, []string{}}
}
return &BaseObject{
Id: id,
Type: objType[0],
}, nil
}
type EmptyBaseObject struct{} type EmptyBaseObject struct{}
func (e *EmptyBaseObject) GetSelfOrBase() (BaseApChain, bool) { func (e *EmptyBaseObject) GetSelfOrBase() (BaseApChain, bool) {

View file

@ -515,23 +515,29 @@ func ParseASOutboxData(raw map[string]any, next BaseApChain) (BaseApChain, error
} }
type ASObjectData struct { type ASObjectData struct {
FullIdType Next BaseApChain
// Unparsed objects. Please parse yourself. Go doesn't like the recursion if the parser for this attribute was calling Unmarshal
Objects []map[string]any
} }
func (object *ASObjectData) GetSelfOrBase() (BaseApChain, bool) { func (object *ASObjectData) GetSelfOrBase() (BaseApChain, bool) {
return object.FullIdType.Next, true return object.Next, true
} }
func (object *ASObjectData) MarshalToMap() map[string]any { func (object *ASObjectData) MarshalToMap() map[string]any {
return object.FullIdType.MarshalToMapWithName(KEY_ACTIVITYSTREAMS_OBJECT) return appendWithKey(object.Next.MarshalToMap(), KEY_ACTIVITYSTREAMS_OBJECT, object.Objects)
} }
func ParseASObjectData(raw map[string]any, next BaseApChain) (BaseApChain, error) { func ParseASObjectData(raw map[string]any, next BaseApChain) (BaseApChain, error) {
id, err := ParseIdTypeWithName(raw, next, KEY_ACTIVITYSTREAMS_OBJECT) rawData1, ok := raw[KEY_ACTIVITYSTREAMS_OBJECT]
if err != nil { if !ok {
return nil, err return nil, NoRequiredFieldError{KEY_ACTIVITYSTREAMS_OBJECT}
} }
return &ASObjectData{FullIdType: *id}, nil data, ok := rawData1.([]map[string]any)
if !ok {
return nil, BadFieldValueError[[]map[string]any]{KEY_ACTIVITYSTREAMS_OBJECT, rawData1, data}
}
return &ASObjectData{Next: next, Objects: data}, nil
} }
type ASPreferredNameData struct { type ASPreferredNameData struct {

58
nsUndefined.go Normal file
View file

@ -0,0 +1,58 @@
package goap
type UDIdData struct {
Next BaseApChain
Id string
}
func (u *UDIdData) GetSelfOrBase() (BaseApChain, bool) {
return u.Next, true
}
func (b *UDIdData) MarshalToMap() map[string]any {
return appendWithKey(b.Next.MarshalToMap(), "KEY_ID", b.Id)
}
func ParseUDIdData(raw map[string]any, next BaseApChain) (BaseApChain, error) {
rawId, ok := raw[KEY_ID]
if !ok {
return nil, NoRequiredFieldError{KEY_ID}
}
id, ok := rawId.(string)
if !ok {
return nil, BadFieldValueError[string]{KEY_ID, rawId, ""}
}
delete(raw, KEY_ID)
return &UDIdData{
Next: next,
Id: id,
}, nil
}
type UDTypeData struct {
Next BaseApChain
Type string
}
func (u *UDTypeData) GetSelfOrBase() (BaseApChain, bool) {
return u.Next, true
}
func (u *UDTypeData) MarshalToMap() map[string]any {
return appendWithKey(u.Next.MarshalToMap(), KEY_TYPE, []any{u.Type})
}
func ParseUDTypeData(raw map[string]any, next BaseApChain) (BaseApChain, error) {
rawObjType, ok := raw[KEY_TYPE]
if !ok {
return nil, NoRequiredFieldError{KEY_TYPE}
}
objType, ok := rawObjType.([]string)
if !ok {
return nil, BadFieldValueError[[]string]{KEY_TYPE, rawObjType, []string{}}
}
if len(objType) != 1 {
return nil, BadFieldArrayLengthError{KEY_TYPE, 1, len(objType)}
}
return &UDTypeData{Next: next, Type: objType[0]}, nil
}

View file

@ -1,8 +1,15 @@
package goap package goap
import "slices" import (
"fmt"
"slices"
"github.com/piprate/json-gold/ld"
)
var allInternalParsersExceptBase []UnmarshalFunc = []UnmarshalFunc{ var allInternalParsersExceptBase []UnmarshalFunc = []UnmarshalFunc{
ParseUDIdData,
ParseUDTypeData,
ParseASActorData, ParseASActorData,
ParseASAlsoKnownAsData, ParseASAlsoKnownAsData,
ParseASAttachmentsData, ParseASAttachmentsData,
@ -75,24 +82,34 @@ func chainParse(
return current, errors return current, errors
} }
func ParseEmptyBase(raw map[string]any, extraParsers ...UnmarshalFunc) (BaseApChain, []error) { func Unmarshal(
base := EmptyBaseObject{} raw []byte,
ldOptions *ld.JsonLdOptions,
processor *ld.JsonLdProcessor,
extraParsers ...UnmarshalFunc,
) (BaseApChain, []error) {
if ldOptions == nil {
ldOptions = ld.NewJsonLdOptions("")
}
if processor == nil {
processor = ld.NewJsonLdProcessor()
}
rawData, err := processor.Expand(raw, ldOptions)
if err != nil {
return nil, []error{err}
}
data, ok := rawData[0].(map[string]any)
if !ok {
return nil, []error{fmt.Errorf("failed to cast expand result into map[string]any")}
}
return UnmarshalPreprocessed(data, extraParsers...)
}
allParsers := slices.Clone(allInternalParsersExceptBase) func UnmarshalPreprocessed(
allParsers = append(allParsers, extraParsers...) raw map[string]any,
extraParsers ...UnmarshalFunc,
) (BaseApChain, []error) {
base := EmptyBaseObject{}
allParsers := slices.Concat(allInternalParsersExceptBase, extraParsers)
return chainParse(raw, &base, allParsers...) return chainParse(raw, &base, allParsers...)
} }
func ParseDefaultBase(raw map[string]any, extraParsers ...UnmarshalFunc) (BaseApChain, []error) {
base, err := UnmarshalBaseObject(raw, nil)
if err != nil {
return base, []error{err}
}
allParsers := slices.Concat(allInternalParsersExceptBase, extraParsers)
res, errs := chainParse(raw, base, allParsers...)
return res, slices.Insert(errs, 0, err)
}
func MarshalChain(chain BaseApChain) map[string]any {
return chain.MarshalToMap()
}