Adding gob encode/decode functionality for *Collection types

This commit is contained in:
mariusor 2022-01-12 18:57:45 +01:00
parent 80679b32e9
commit 3e9850f7d0
No known key found for this signature in database
GPG key ID: DBF5E47F5DBC4D21
6 changed files with 357 additions and 40 deletions

View file

@ -1,6 +1,8 @@
package activitypub
import (
"bytes"
"encoding/gob"
"errors"
"reflect"
"time"
@ -270,25 +272,43 @@ func (c Collection) MarshalJSON() ([]byte, error) {
return nil, nil
}
/*
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
func (c *Collection) UnmarshalBinary(data []byte) error {
return errors.New(fmt.Sprintf("UnmarshalBinary is not implemented for %T", *c))
return c.GobDecode(data)
}
// MarshalBinary implements the encoding.BinaryMarshaler interface.
func (c Collection) MarshalBinary() ([]byte, error) {
return nil, errors.New(fmt.Sprintf("MarshalBinary is not implemented for %T", c))
return c.GobEncode()
}
func (c Collection) GobEncode() ([]byte, error) {
return nil, errors.New(fmt.Sprintf("GobEncode is not implemented for %T", c))
var mm = make(map[string][]byte)
hasData, err := mapCollectionProperties(mm, c)
if err != nil {
return nil, err
}
if !hasData {
return []byte{}, nil
}
bb := bytes.Buffer{}
g := gob.NewEncoder(&bb)
if err := g.Encode(mm); err != nil {
return nil, err
}
return bb.Bytes(), nil
}
func (c *Collection) GobDecode([]byte) error {
return errors.New(fmt.Sprintf("GobDecode is not implemented for %T", *c))
func (c *Collection) GobDecode(data []byte) error {
if len(data) == 0 {
return nil
}
mm, err := gobDecodeObjectAsMap(data)
if err != nil {
return err
}
return unmapCollectionProperties(mm, c)
}
*/
// ToCollection
func ToCollection(it Item) (*Collection, error) {

View file

@ -1,6 +1,8 @@
package activitypub
import (
"bytes"
"encoding/gob"
"errors"
"reflect"
"time"
@ -234,25 +236,43 @@ func (c CollectionPage) MarshalJSON() ([]byte, error) {
return nil, nil
}
/*
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
func (c *CollectionPage) UnmarshalBinary(data []byte) error {
return errors.New(fmt.Sprintf("UnmarshalBinary is not implemented for %T", *c))
return c.GobDecode(data)
}
// MarshalBinary implements the encoding.BinaryMarshaler interface.
func (c CollectionPage) MarshalBinary() ([]byte, error) {
return nil, errors.New(fmt.Sprintf("MarshalBinary is not implemented for %T", c))
return c.GobEncode()
}
func (c CollectionPage) GobEncode() ([]byte, error) {
return nil, errors.New(fmt.Sprintf("GobEncode is not implemented for %T", c))
var mm = make(map[string][]byte)
hasData, err := mapCollectionPageProperties(mm, c)
if err != nil {
return nil, err
}
if !hasData {
return []byte{}, nil
}
bb := bytes.Buffer{}
g := gob.NewEncoder(&bb)
if err := g.Encode(mm); err != nil {
return nil, err
}
return bb.Bytes(), nil
}
func (c *CollectionPage) GobDecode([]byte) error {
return errors.New(fmt.Sprintf("GobDecode is not implemented for %T", *c))
func (c *CollectionPage) GobDecode(data []byte) error {
if len(data) == 0 {
return nil
}
mm, err := gobDecodeObjectAsMap(data)
if err != nil {
return err
}
return unmapCollectionPageProperties(mm, c)
}
*/
// CollectionNew initializes a new CollectionPage
func CollectionPageNew(parent CollectionInterface) *CollectionPage {

View file

@ -481,3 +481,111 @@ func gobDecodeObjectAsMap(data []byte) (map[string][]byte, error) {
}
return mm, nil
}
func unmapIncompleteCollectionProperties(mm map[string][]byte, c *Collection) error {
err := OnObject(c, func(ob *Object) error {
return unmapObjectProperties(mm, ob)
})
if err != nil {
return err
}
if raw, ok := mm["current"]; ok {
if c.Current, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["first"]; ok {
if c.First, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["last"]; ok {
if c.Last, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["totalItems"]; ok {
if err = gobDecodeUint(&c.TotalItems, raw); err != nil {
return err
}
}
return nil
}
func unmapCollectionProperties(mm map[string][]byte, c *Collection) error {
err := unmapIncompleteCollectionProperties(mm, c)
if err != nil {
return err
}
if raw, ok := mm["items"]; ok {
if c.Items, err = gobDecodeItems(raw); err != nil {
return err
}
}
return err
}
func unmapCollectionPageProperties(mm map[string][]byte, c *CollectionPage) error {
err := OnCollection(c, func(c *Collection) error {
return unmapCollectionProperties(mm, c)
})
if err != nil {
return err
}
if raw, ok := mm["partOf"]; ok {
if c.PartOf, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["next"]; ok {
if c.Next, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["prev"]; ok {
if c.Prev, err = gobDecodeItem(raw); err != nil {
return err
}
}
return err
}
func unmapOrderedCollectionProperties(mm map[string][]byte, o *OrderedCollection) error {
err := OnCollection(o, func(c *Collection) error {
return unmapIncompleteCollectionProperties(mm, c)
})
if err != nil {
return err
}
if raw, ok := mm["orderedItems"]; ok {
if o.OrderedItems, err = gobDecodeItems(raw); err != nil {
return err
}
}
return err
}
func unmapOrderedCollectionPageProperties(mm map[string][]byte, c *OrderedCollectionPage) error {
err := OnOrderedCollection(c, func(c *OrderedCollection) error {
return unmapOrderedCollectionProperties(mm, c)
})
if err != nil {
return err
}
if raw, ok := mm["partOf"]; ok {
if c.PartOf, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["next"]; ok {
if c.Next, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["prev"]; ok {
if c.Prev, err = gobDecodeItem(raw); err != nil {
return err
}
}
return err
}

View file

@ -26,6 +26,20 @@ func gobEncodeUint(i uint) ([]byte, error) {
return b.Bytes(), nil
}
func gobEncodeItems(col ItemCollection) ([]byte, error) {
b := bytes.Buffer{}
tt := make([][]byte, 0)
for _, it := range col.Collection() {
single, err := gobEncodeItem(it)
if err != nil {
return nil, err
}
tt = append(tt, single)
}
err := gob.NewEncoder(&b).Encode(tt)
return b.Bytes(), err
}
func gobEncodeItem(it Item) ([]byte, error) {
b := bytes.Buffer{}
var err error
@ -34,16 +48,11 @@ func gobEncodeItem(it Item) ([]byte, error) {
err = gobEncodeStringLikeType(g, []byte(it.GetLink()))
}
if IsItemCollection(it) {
g := gob.NewEncoder(&b)
tt := make([][]byte, 0)
err = OnItemCollection(it, func(col *ItemCollection) error {
for _, it := range col.Collection() {
single, _ := gobEncodeItem(it)
tt = append(tt, single)
}
return nil
bytes, err := gobEncodeItems(*col)
b.Write(bytes)
return err
})
err = g.Encode(tt)
}
switch it.GetType() {
case IRIType:
@ -84,19 +93,27 @@ func gobEncodeItem(it Item) ([]byte, error) {
})
case CollectionType:
err = OnCollection(it, func(c *Collection) error {
return fmt.Errorf("TODO: Implement encode of %T", c)
bytes, err := c.GobEncode()
b.Write(bytes)
return err
})
case OrderedCollectionType:
err = OnOrderedCollection(it, func(c *OrderedCollection) error {
return fmt.Errorf("TODO: Implement encode of %T", c)
bytes, err := c.GobEncode()
b.Write(bytes)
return err
})
case CollectionPageType:
err = OnCollectionPage(it, func(p *CollectionPage) error {
return fmt.Errorf("TODO: Implement encode of %T", p)
bytes, err := p.GobEncode()
b.Write(bytes)
return err
})
case OrderedCollectionPageType:
err = OnOrderedCollectionPage(it, func(p *OrderedCollectionPage) error {
return fmt.Errorf("TODO: Implement encode of %T", p)
bytes, err := p.GobEncode()
b.Write(bytes)
return err
})
case PlaceType:
err = OnPlace(it, func(p *Place) error {
@ -404,3 +421,115 @@ func mapActorProperties(mm map[string][]byte, a *Actor) (hasData bool, err error
}
return hasData, err
}
func mapIncompleteCollectionProperties(mm map[string][]byte, c Collection) (hasData bool, err error) {
err = OnObject(c, func(o *Object) error {
hasData, err = mapObjectProperties(mm, o)
return err
})
if c.Current != nil {
if mm["current"], err = gobEncodeItem(c.Current); err != nil {
return hasData, err
}
hasData = true
}
if c.First != nil {
if mm["first"], err = gobEncodeItem(c.First); err != nil {
return hasData, err
}
hasData = true
}
if c.Last != nil {
if mm["last"], err = gobEncodeItem(c.Last); err != nil {
return hasData, err
}
hasData = true
}
if c.TotalItems > 0 {
hasData = true
}
if mm["totalItems"], err = gobEncodeUint(c.TotalItems); err != nil {
return hasData, err
}
return
}
func mapCollectionProperties(mm map[string][]byte, c Collection) (hasData bool, err error) {
hasData, err = mapIncompleteCollectionProperties(mm, c)
if err != nil {
return hasData, err
}
if c.Items != nil {
if mm["items"], err = gobEncodeItems(c.Items); err != nil {
return hasData, err
}
hasData = true
}
return
}
func mapOrderedCollectionProperties(mm map[string][]byte, c OrderedCollection) (hasData bool, err error) {
err = OnCollection(c, func(c *Collection) error {
hasData, err = mapIncompleteCollectionProperties(mm, *c)
return err
})
if c.OrderedItems != nil {
if mm["orderedItems"], err = gobEncodeItems(c.OrderedItems); err != nil {
return hasData, err
}
hasData = true
}
return
}
func mapCollectionPageProperties(mm map[string][]byte, c CollectionPage) (hasData bool, err error) {
err = OnCollection(c, func(c *Collection) error {
hasData, err = mapCollectionProperties(mm, *c)
return err
})
if c.PartOf != nil {
if mm["partOf"], err = gobEncodeItem(c.PartOf); err != nil {
return hasData, err
}
hasData = true
}
if c.Next != nil {
if mm["next"], err = gobEncodeItem(c.Next); err != nil {
return hasData, err
}
hasData = true
}
if c.Prev != nil {
if mm["prev"], err = gobEncodeItem(c.Prev); err != nil {
return hasData, err
}
hasData = true
}
return
}
func mapOrderedCollectionPageProperties(mm map[string][]byte, c OrderedCollectionPage) (hasData bool, err error) {
err = OnOrderedCollection(c, func(c *OrderedCollection) error {
hasData, err = mapOrderedCollectionProperties(mm, *c)
return err
})
if c.PartOf != nil {
if mm["partOf"], err = gobEncodeItem(c.PartOf); err != nil {
return hasData, err
}
hasData = true
}
if c.Next != nil {
if mm["next"], err = gobEncodeItem(c.Next); err != nil {
return hasData, err
}
hasData = true
}
if c.Prev != nil {
if mm["prev"], err = gobEncodeItem(c.Prev); err != nil {
return hasData, err
}
hasData = true
}
return
}

View file

@ -1,6 +1,8 @@
package activitypub
import (
"bytes"
"encoding/gob"
"errors"
"reflect"
"time"
@ -266,27 +268,45 @@ func (o OrderedCollection) MarshalJSON() ([]byte, error) {
return nil, nil
}
/*
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
func (o *OrderedCollection) UnmarshalBinary(data []byte) error {
return errors.New(fmt.Sprintf("UnmarshalBinary is not implemented for %T", *o))
return o.GobDecode(data)
}
// MarshalBinary implements the encoding.BinaryMarshaler interface.
func (o OrderedCollection) MarshalBinary() ([]byte, error) {
return nil, errors.New(fmt.Sprintf("MarshalBinary is not implemented for %T", o))
return o.GobEncode()
}
// GobEncode
func (o OrderedCollection) GobEncode() ([]byte, error) {
return nil, errors.New(fmt.Sprintf("GobEncode is not implemented for %T", o))
var mm = make(map[string][]byte)
hasData, err := mapOrderedCollectionProperties(mm, o)
if err != nil {
return nil, err
}
if !hasData {
return []byte{}, nil
}
bb := bytes.Buffer{}
g := gob.NewEncoder(&bb)
if err := g.Encode(mm); err != nil {
return nil, err
}
return bb.Bytes(), nil
}
// GobDecode
func (o *OrderedCollection) GobDecode([]byte) error {
return errors.New(fmt.Sprintf("GobDecode is not implemented for %T", *o))
func (o *OrderedCollection) GobDecode(data []byte) error {
if len(data) == 0 {
return nil
}
mm, err := gobDecodeObjectAsMap(data)
if err != nil {
return err
}
return unmapOrderedCollectionProperties(mm, o)
}
*/
// OrderedCollectionPageNew initializes a new OrderedCollectionPage
func OrderedCollectionPageNew(parent CollectionInterface) *OrderedCollectionPage {

View file

@ -1,6 +1,8 @@
package activitypub
import (
"bytes"
"encoding/gob"
"errors"
"reflect"
"time"
@ -237,27 +239,45 @@ func (o OrderedCollectionPage) MarshalJSON() ([]byte, error) {
return nil, nil
}
/*
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
func (o *OrderedCollectionPage) UnmarshalBinary(data []byte) error {
return errors.New(fmt.Sprintf("UnmarshalBinary is not implemented for %T", *o))
return o.GobDecode(data)
}
// MarshalBinary implements the encoding.BinaryMarshaler interface.
func (o OrderedCollectionPage) MarshalBinary() ([]byte, error) {
return nil, errors.New(fmt.Sprintf("MarshalBinary is not implemented for %T", o))
return o.GobEncode()
}
// GobEncode
func (o OrderedCollectionPage) GobEncode() ([]byte, error) {
return nil, errors.New(fmt.Sprintf("GobEncode is not implemented for %T", o))
var mm = make(map[string][]byte)
hasData, err := mapOrderedCollectionPageProperties(mm, o)
if err != nil {
return nil, err
}
if !hasData {
return []byte{}, nil
}
bb := bytes.Buffer{}
g := gob.NewEncoder(&bb)
if err := g.Encode(mm); err != nil {
return nil, err
}
return bb.Bytes(), nil
}
// GobDecode
func (o *OrderedCollectionPage) GobDecode([]byte) error {
return errors.New(fmt.Sprintf("GobDecode is not implemented for %T", *o))
func (o *OrderedCollectionPage) GobDecode(data []byte) error {
if len(data) == 0 {
return nil
}
mm, err := gobDecodeObjectAsMap(data)
if err != nil {
return err
}
return unmapOrderedCollectionPageProperties(mm, o)
}
*/
// ToOrderedCollectionPage
func ToOrderedCollectionPage(it Item) (*OrderedCollectionPage, error) {