Added gob Marshal/Unmarshal for Link type
Testing is still incomplete for this
This commit is contained in:
parent
a7d54ee31e
commit
525748448c
145
link.go
145
link.go
|
@ -1,6 +1,9 @@
|
||||||
package activitypub
|
package activitypub
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/gob"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/valyala/fastjson"
|
"github.com/valyala/fastjson"
|
||||||
|
@ -116,20 +119,150 @@ func (l *Link) UnmarshalJSON(data []byte) error {
|
||||||
|
|
||||||
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
||||||
func (l *Link) UnmarshalBinary(data []byte) error {
|
func (l *Link) UnmarshalBinary(data []byte) error {
|
||||||
return fmt.Errorf("UnmarshalBinary is not implemented for %T", *l)
|
return l.GobDecode(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
||||||
func (l Link) MarshalBinary() ([]byte, error) {
|
func (l Link) MarshalBinary() ([]byte, error) {
|
||||||
return nil, errors.New(fmt.Sprintf("MarshalBinary is not implemented for %T", l))
|
return l.GobEncode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(marius): when migrating to go1.18, use a numeric constraint for this
|
||||||
|
func gobEncodeUint(i uint) ([]byte, error) {
|
||||||
|
b := bytes.Buffer{}
|
||||||
|
gg := gob.NewEncoder(&b)
|
||||||
|
if err := gg.Encode(i); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return b.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Link) GobEncode() ([]byte, error) {
|
func (l Link) GobEncode() ([]byte, error) {
|
||||||
return nil, errors.New(fmt.Sprintf("GobEncode is not implemented for %T", l))
|
var (
|
||||||
|
mm = make(map[string][]byte)
|
||||||
|
err error
|
||||||
|
hasData bool
|
||||||
|
)
|
||||||
|
if len(l.ID) > 0 {
|
||||||
|
if mm["id"], err = l.ID.GobEncode(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasData = true
|
||||||
|
}
|
||||||
|
if len(l.Type) > 0 {
|
||||||
|
if mm["type"], err = l.Type.GobEncode(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasData = true
|
||||||
|
}
|
||||||
|
if len(l.MediaType) > 0 {
|
||||||
|
if mm["mediaType"], err = l.MediaType.GobEncode(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasData = true
|
||||||
|
}
|
||||||
|
if len(l.Href) > 0 {
|
||||||
|
if mm["href"], err = l.Href.GobEncode(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasData = true
|
||||||
|
}
|
||||||
|
if len(l.HrefLang) > 0 {
|
||||||
|
if mm["hrefLang"], err = l.HrefLang.GobEncode(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasData = true
|
||||||
|
}
|
||||||
|
if len(l.Name) > 0 {
|
||||||
|
if mm["name"], err = l.Name.GobEncode(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasData = true
|
||||||
|
}
|
||||||
|
if len(l.Rel) > 0 {
|
||||||
|
if mm["rel"], err = l.Rel.GobEncode(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasData = true
|
||||||
|
}
|
||||||
|
if l.Width > 0 {
|
||||||
|
if mm["width"], err = gobEncodeUint(l.Width); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasData = true
|
||||||
|
}
|
||||||
|
if l.Height > 0 {
|
||||||
|
if mm["height"], err = gobEncodeUint(l.Height); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hasData = true
|
||||||
|
}
|
||||||
|
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 (l *Link) GobDecode([]byte) error {
|
func gobDecodeUint(i *uint, data []byte) error {
|
||||||
|
g := gob.NewDecoder(bytes.NewReader(data))
|
||||||
|
return g.Decode(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Link) GobDecode(data []byte) error {
|
||||||
|
mm := make(map[string][]byte)
|
||||||
|
g := gob.NewDecoder(bytes.NewReader(data))
|
||||||
|
if err := g.Decode(&mm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if raw, ok := mm["id"]; ok {
|
||||||
|
if err := l.ID.GobDecode(raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if raw, ok := mm["type"]; ok {
|
||||||
|
if err := l.Type.GobDecode(raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if raw, ok := mm["mediaType"]; ok {
|
||||||
|
if err := l.MediaType.GobDecode(raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if raw, ok := mm["href"]; ok {
|
||||||
|
if err := l.Href.GobDecode(raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if raw, ok := mm["hrefLang"]; ok {
|
||||||
|
if err := l.HrefLang.GobDecode(raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if raw, ok := mm["name"]; ok {
|
||||||
|
if err := l.Name.GobDecode(raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if raw, ok := mm["rel"]; ok {
|
||||||
|
if err := l.Rel.GobDecode(raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if raw, ok := mm["width"]; ok {
|
||||||
|
if err := gobDecodeUint(&l.Width, raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if raw, ok := mm["height"]; ok {
|
||||||
|
if err := gobDecodeUint(&l.Height, raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return errors.New(fmt.Sprintf("GobDecode is not implemented for %T", *l))
|
return errors.New(fmt.Sprintf("GobDecode is not implemented for %T", *l))
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
100
link_test.go
100
link_test.go
|
@ -1,6 +1,7 @@
|
||||||
package activitypub
|
package activitypub
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -63,3 +64,102 @@ func TestMentionNew(t *testing.T) {
|
||||||
func TestLink_IsCollection(t *testing.T) {
|
func TestLink_IsCollection(t *testing.T) {
|
||||||
t.Skipf("TODO")
|
t.Skipf("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLink_GobEncode(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
ID ID
|
||||||
|
Type ActivityVocabularyType
|
||||||
|
Name NaturalLanguageValues
|
||||||
|
Rel IRI
|
||||||
|
MediaType MimeType
|
||||||
|
Height uint
|
||||||
|
Width uint
|
||||||
|
Preview Item
|
||||||
|
Href IRI
|
||||||
|
HrefLang LangRef
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
want []byte
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
fields: fields{},
|
||||||
|
want: []byte{},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
l := Link{
|
||||||
|
ID: tt.fields.ID,
|
||||||
|
Type: tt.fields.Type,
|
||||||
|
Name: tt.fields.Name,
|
||||||
|
Rel: tt.fields.Rel,
|
||||||
|
MediaType: tt.fields.MediaType,
|
||||||
|
Height: tt.fields.Height,
|
||||||
|
Width: tt.fields.Width,
|
||||||
|
Preview: tt.fields.Preview,
|
||||||
|
Href: tt.fields.Href,
|
||||||
|
HrefLang: tt.fields.HrefLang,
|
||||||
|
}
|
||||||
|
got, err := l.GobEncode()
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("GobEncode() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("GobEncode() got = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLink_GobDecode(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
ID ID
|
||||||
|
Type ActivityVocabularyType
|
||||||
|
Name NaturalLanguageValues
|
||||||
|
Rel IRI
|
||||||
|
MediaType MimeType
|
||||||
|
Height uint
|
||||||
|
Width uint
|
||||||
|
Preview Item
|
||||||
|
Href IRI
|
||||||
|
HrefLang LangRef
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
data []byte
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
fields: fields{},
|
||||||
|
data: []byte{},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
l := &Link{
|
||||||
|
ID: tt.fields.ID,
|
||||||
|
Type: tt.fields.Type,
|
||||||
|
Name: tt.fields.Name,
|
||||||
|
Rel: tt.fields.Rel,
|
||||||
|
MediaType: tt.fields.MediaType,
|
||||||
|
Height: tt.fields.Height,
|
||||||
|
Width: tt.fields.Width,
|
||||||
|
Preview: tt.fields.Preview,
|
||||||
|
Href: tt.fields.Href,
|
||||||
|
HrefLang: tt.fields.HrefLang,
|
||||||
|
}
|
||||||
|
if err := l.GobDecode(tt.data); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("GobDecode() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in a new issue