This repository has been archived on 2022-11-27. You can view files and clone it, but cannot push or open issues or pull requests.
activitypub/decoding_gob.go

734 lines
17 KiB
Go

package activitypub
import (
"bytes"
"encoding/gob"
"errors"
"time"
)
func GobDecode(data []byte) (Item, error) {
return gobDecodeItem(data)
}
func gobDecodeUint(i *uint, data []byte) error {
g := gob.NewDecoder(bytes.NewReader(data))
return g.Decode(i)
}
func gobDecodeFloat64(f *float64, data []byte) error {
g := gob.NewDecoder(bytes.NewReader(data))
return g.Decode(f)
}
func gobDecodeInt64(i *int64, data []byte) error {
g := gob.NewDecoder(bytes.NewReader(data))
return g.Decode(i)
}
func gobDecodeBool(b *bool, data []byte) error {
g := gob.NewDecoder(bytes.NewReader(data))
return g.Decode(b)
}
func unmapActorProperties(mm map[string][]byte, a *Actor) error {
err := OnObject(a, func(ob *Object) error {
return unmapObjectProperties(mm, ob)
})
if err != nil {
return err
}
if raw, ok := mm["inbox"]; ok {
if a.Inbox, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["outbox"]; ok {
if a.Outbox, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["following"]; ok {
if a.Following, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["followers"]; ok {
if a.Followers, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["liked"]; ok {
if a.Liked, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["preferredUsername"]; ok {
if a.PreferredUsername, err = gobDecodeNaturalLanguageValues(raw); err != nil {
return err
}
}
if raw, ok := mm["endpoints"]; ok {
if err = a.Endpoints.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["streams"]; ok {
if a.Streams, err = gobDecodeItems(raw); err != nil {
return err
}
}
if raw, ok := mm["publicKey"]; ok {
if err = a.PublicKey.GobDecode(raw); err != nil {
return err
}
}
return nil
}
func unmapIntransitiveActivityProperties(mm map[string][]byte, act *IntransitiveActivity) error {
err := OnObject(act, func(ob *Object) error {
return unmapObjectProperties(mm, ob)
})
if err != nil {
return err
}
if raw, ok := mm["actor"]; ok {
if act.Actor, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["target"]; ok {
if act.Target, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["result"]; ok {
if act.Result, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["origin"]; ok {
if act.Origin, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["instrument"]; ok {
if act.Instrument, err = gobDecodeItem(raw); err != nil {
return err
}
}
return nil
}
func unmapActivityProperties(mm map[string][]byte, act *Activity) error {
err := OnIntransitiveActivity(act, func(act *IntransitiveActivity) error {
return unmapIntransitiveActivityProperties(mm, act)
})
if err != nil {
return err
}
if raw, ok := mm["object"]; ok {
if act.Object, err = gobDecodeItem(raw); err != nil {
return err
}
}
return nil
}
func unmapLinkProperties(mm map[string][]byte, l *Link) error {
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 nil
}
func unmapObjectProperties(mm map[string][]byte, o *Object) error {
var err error
if raw, ok := mm["id"]; ok {
if err = o.ID.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["type"]; ok {
if err = o.Type.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["name"]; ok {
if err = o.Name.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["attachment"]; ok {
if o.Attachment, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["attributedTo"]; ok {
if o.AttributedTo, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["audience"]; ok {
if o.Audience, err = gobDecodeItems(raw); err != nil {
return err
}
}
if raw, ok := mm["content"]; ok {
if o.Content, err = gobDecodeNaturalLanguageValues(raw); err != nil {
return err
}
}
if raw, ok := mm["context"]; ok {
if o.Context, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["mediaType"]; ok {
if err = o.MediaType.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["endTime"]; ok {
if err = o.EndTime.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["generator"]; ok {
if o.Generator, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["icon"]; ok {
if o.Icon, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["image"]; ok {
if o.Image, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["inReplyTo"]; ok {
if o.InReplyTo, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["location"]; ok {
if o.Location, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["preview"]; ok {
if o.Preview, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["published"]; ok {
if err = o.Published.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["replies"]; ok {
if o.Replies, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["startTime"]; ok {
if err = o.StartTime.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["summary"]; ok {
if o.Summary, err = gobDecodeNaturalLanguageValues(raw); err != nil {
return err
}
}
if raw, ok := mm["tag"]; ok {
if o.Tag, err = gobDecodeItems(raw); err != nil {
return err
}
}
if raw, ok := mm["updated"]; ok {
if err = o.Updated.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["url"]; ok {
if o.URL, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["to"]; ok {
if o.To, err = gobDecodeItems(raw); err != nil {
return err
}
}
if raw, ok := mm["bto"]; ok {
if o.Bto, err = gobDecodeItems(raw); err != nil {
return err
}
}
if raw, ok := mm["cc"]; ok {
if o.CC, err = gobDecodeItems(raw); err != nil {
return err
}
}
if raw, ok := mm["bcc"]; ok {
if o.BCC, err = gobDecodeItems(raw); err != nil {
return err
}
}
if raw, ok := mm["duration"]; ok {
if o.Duration, err = gobDecodeDuration(raw); err != nil {
return err
}
}
if raw, ok := mm["likes"]; ok {
if o.Likes, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["shares"]; ok {
if o.Shares, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["source"]; ok {
if err := o.Source.GobDecode(raw); err != nil {
return err
}
}
return nil
}
func tryDecodeObject(ob *Object, data []byte) error {
if err := ob.GobDecode(data); err != nil {
return err
}
return nil
}
func tryDecodeItems(items *ItemCollection, data []byte) error {
tt := make([][]byte, 0)
g := gob.NewDecoder(bytes.NewReader(data))
if err := g.Decode(&tt); err != nil {
return err
}
for _, it := range tt {
ob, err := gobDecodeItem(it)
if err != nil {
return err
}
*items = append(*items, ob)
}
return nil
}
func tryDecodeIRIs(iris *IRIs, data []byte) error {
return iris.GobDecode(data)
}
func tryDecodeIRI(iri *IRI, data []byte) error {
return iri.GobDecode(data)
}
func gobDecodeDuration(data []byte) (time.Duration, error) {
var d time.Duration
err := gob.NewDecoder(bytes.NewReader(data)).Decode(&d)
return d, err
}
func gobDecodeNaturalLanguageValues(data []byte) (NaturalLanguageValues, error) {
n := make(NaturalLanguageValues, 0)
err := n.GobDecode(data)
return n, err
}
func gobDecodeItems(data []byte) (ItemCollection, error) {
items := make(ItemCollection, 0)
if err := tryDecodeItems(&items, data); err != nil {
return nil, err
}
return items, nil
}
func gobDecodeItem(data []byte) (Item, error) {
items := make(ItemCollection, 0)
if err := tryDecodeItems(&items, data); err == nil {
return items, nil
}
iris := make(IRIs, 0)
if err := tryDecodeIRIs(&iris, data); err == nil {
it := make(ItemCollection, len(iris))
for i, iri := range iris {
it[i] = iri
}
return it, nil
}
isObject := false
typ := ObjectType
mm, err := gobDecodeObjectAsMap(data)
if err == nil {
var sTyp []byte
sTyp, isObject = mm["type"]
if isObject {
typ = ActivityVocabularyType(sTyp)
} else {
_, isObject = mm["id"]
}
}
if isObject {
it, err := ItemTyperFunc(typ)
if err != nil {
return nil, err
}
switch it.GetType() {
case IRIType:
case "", ObjectType, ArticleType, AudioType, DocumentType, EventType, ImageType, NoteType, PageType, VideoType:
err = OnObject(it, func(ob *Object) error {
return unmapObjectProperties(mm, ob)
})
case LinkType, MentionType:
err = OnLink(it, func(l *Link) error {
return unmapLinkProperties(mm, l)
})
case ActivityType, AcceptType, AddType, AnnounceType, BlockType, CreateType, DeleteType, DislikeType,
FlagType, FollowType, IgnoreType, InviteType, JoinType, LeaveType, LikeType, ListenType, MoveType, OfferType,
RejectType, ReadType, RemoveType, TentativeRejectType, TentativeAcceptType, UndoType, UpdateType, ViewType:
err = OnActivity(it, func(act *Activity) error {
return unmapActivityProperties(mm, act)
})
case IntransitiveActivityType, ArriveType, TravelType:
err = OnIntransitiveActivity(it, func(act *IntransitiveActivity) error {
return unmapIntransitiveActivityProperties(mm, act)
})
case ActorType, ApplicationType, GroupType, OrganizationType, PersonType, ServiceType:
err = OnActor(it, func(a *Actor) error {
return unmapActorProperties(mm, a)
})
case CollectionType:
err = OnCollection(it, func(c *Collection) error {
return unmapCollectionProperties(mm, c)
})
case OrderedCollectionType:
err = OnOrderedCollection(it, func(c *OrderedCollection) error {
return unmapOrderedCollectionProperties(mm, c)
})
case CollectionPageType:
err = OnCollectionPage(it, func(p *CollectionPage) error {
return unmapCollectionPageProperties(mm, p)
})
case OrderedCollectionPageType:
err = OnOrderedCollectionPage(it, func(p *OrderedCollectionPage) error {
return unmapOrderedCollectionPageProperties(mm, p)
})
case PlaceType:
err = OnPlace(it, func(p *Place) error {
return unmapPlaceProperties(mm, p)
})
case ProfileType:
err = OnProfile(it, func(p *Profile) error {
return unmapProfileProperties(mm, p)
})
case RelationshipType:
err = OnRelationship(it, func(r *Relationship) error {
return unmapRelationshipProperties(mm, r)
})
case TombstoneType:
err = OnTombstone(it, func(t *Tombstone) error {
return unmapTombstoneProperties(mm, t)
})
case QuestionType:
err = OnQuestion(it, func(q *Question) error {
return unmapQuestionProperties(mm, q)
})
}
return it, err
}
iri := IRI("")
if err := tryDecodeIRI(&iri, data); err == nil {
return iri, err
}
return nil, errors.New("unable to gob decode to any known ActivityPub types")
}
func gobDecodeObjectAsMap(data []byte) (map[string][]byte, error) {
mm := make(map[string][]byte)
g := gob.NewDecoder(bytes.NewReader(data))
if err := g.Decode(&mm); err != nil {
return nil, err
}
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
}
func unmapPlaceProperties(mm map[string][]byte, p *Place) error {
err := OnObject(p, func(ob *Object) error {
return unmapObjectProperties(mm, ob)
})
if err != nil {
return err
}
if raw, ok := mm["accuracy"]; ok {
if err = gobDecodeFloat64(&p.Accuracy, raw); err != nil {
return err
}
}
if raw, ok := mm["altitude"]; ok {
if err = gobDecodeFloat64(&p.Altitude, raw); err != nil {
return err
}
}
if raw, ok := mm["latitude"]; ok {
if err = gobDecodeFloat64(&p.Latitude, raw); err != nil {
return err
}
}
if raw, ok := mm["radius"]; ok {
if err = gobDecodeInt64(&p.Radius, raw); err != nil {
return err
}
}
if raw, ok := mm["units"]; ok {
p.Units = string(raw)
}
return nil
}
func unmapProfileProperties(mm map[string][]byte, p *Profile) error {
err := OnObject(p, func(ob *Object) error {
return unmapObjectProperties(mm, ob)
})
if err != nil {
return err
}
if raw, ok := mm["Describes"]; ok {
if p.Describes, err = gobDecodeItem(raw); err != nil {
return err
}
}
return nil
}
func unmapRelationshipProperties(mm map[string][]byte, r *Relationship) error {
err := OnObject(r, func(ob *Object) error {
return unmapObjectProperties(mm, ob)
})
if err != nil {
return err
}
if raw, ok := mm["subject"]; ok {
if r.Subject, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["object"]; ok {
if r.Object, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["relationship"]; ok {
if r.Relationship, err = gobDecodeItem(raw); err != nil {
return err
}
}
return nil
}
func unmapTombstoneProperties(mm map[string][]byte, t *Tombstone) error {
err := OnObject(t, func(ob *Object) error {
return unmapObjectProperties(mm, ob)
})
if err != nil {
return err
}
if raw, ok := mm["formerType"]; ok {
if err = t.FormerType.GobDecode(raw); err != nil {
return err
}
}
if raw, ok := mm["deleted"]; ok {
if err = t.Deleted.GobDecode(raw); err != nil {
return err
}
}
return nil
}
func unmapQuestionProperties(mm map[string][]byte, q *Question) error {
err := OnIntransitiveActivity(q, func(act *IntransitiveActivity) error {
return unmapIntransitiveActivityProperties(mm, act)
})
if err != nil {
return err
}
if raw, ok := mm["oneOf"]; ok {
if q.OneOf, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["anyOf"]; ok {
if q.AnyOf, err = gobDecodeItem(raw); err != nil {
return err
}
}
if raw, ok := mm["closed"]; ok {
if err = gobDecodeBool(&q.Closed, raw); err != nil {
return err
}
}
return nil
}