activity/pub/resolvers.go
Cory Slep 701475b6e0 Fix bugs with delivering messages.
This was uncovered during writing tests where both the Social and
Federative APIs are enabled. The actorObject interface was overused
partially due to my earlier confusion; the introduction of the internal
actor interface resolved this.

Finally, the HttpClient interface was introduced to be able to mock out
calls in testing. It may also prove useful for future applications using
this library.
2018-04-04 00:23:55 +02:00

157 行
3.7 KiB
Go

package pub
import (
"fmt"
"github.com/go-fed/activity/streams"
"github.com/go-fed/activity/vocab"
"net/url"
)
// ToPubObject transforms a json-deserialized ActivityStream object into a
// PubObject for use with the pub library. Note that for an object to be an
// ActivityPub object, it must have an 'id' and at least one 'type'.
func ToPubObject(m map[string]interface{}) (t []PubObject, e error) {
r := &streams.Resolver{
AnyObjectCallback: func(i vocab.ObjectType) error {
if !i.HasId() {
return fmt.Errorf("object type does not have an id: %q", i)
} else if i.TypeLen() == 0 {
return fmt.Errorf("object type does not have a type: %q", i)
}
t = append(t, i)
return nil
},
AnyLinkCallback: func(i vocab.LinkType) error {
if !i.HasId() {
return fmt.Errorf("link type does not have an id: %q", i)
} else if i.TypeLen() == 0 {
return fmt.Errorf("link type does not have a type: %q", i)
}
t = append(t, i)
return nil
},
}
e = r.Deserialize(m)
return t, e
}
func getActorObject(m map[string]interface{}) (actorObject, error) {
var a actorObject
err := toActorObjectResolver(&a).Deserialize(m)
return a, err
}
func toActorObjectResolver(a *actorObject) *streams.Resolver {
return &streams.Resolver{
AnyObjectCallback: func(i vocab.ObjectType) error {
if o, ok := i.(actorObject); ok {
*a = o
}
return nil
},
}
}
func toActorResolver(a *actor) *streams.Resolver {
return &streams.Resolver{
AnyObjectCallback: func(i vocab.ObjectType) error {
if o, ok := i.(actor); ok {
*a = o
}
return nil
},
}
}
func toActorCollectionResolver(a *actor, c **streams.Collection, oc **streams.OrderedCollection, cp **streams.CollectionPage, ocp **streams.OrderedCollectionPage) *streams.Resolver {
r := toActorResolver(a)
r.CollectionCallback = func(i *streams.Collection) error {
*c = i
return nil
}
r.OrderedCollectionCallback = func(i *streams.OrderedCollection) error {
*oc = i
return nil
}
r.CollectionPageCallback = func(i *streams.CollectionPage) error {
*cp = i
return nil
}
r.OrderedCollectionPageCallback = func(i *streams.OrderedCollectionPage) error {
*ocp = i
return nil
}
return r
}
func toIdResolver(ok *bool, u *url.URL) *streams.Resolver {
return &streams.Resolver{
AnyObjectCallback: func(i vocab.ObjectType) error {
*ok = i.HasId()
if *ok {
*u = i.GetId()
}
return nil
},
}
}
func toCollectionPage(m map[string]interface{}) (c *streams.CollectionPage, err error) {
r := &streams.Resolver{
CollectionPageCallback: func(i *streams.CollectionPage) error {
c = i
return nil
},
}
err = r.Deserialize(m)
return
}
func toOrderedCollectionPage(m map[string]interface{}) (c *streams.OrderedCollectionPage, err error) {
r := &streams.Resolver{
OrderedCollectionPageCallback: func(i *streams.OrderedCollectionPage) error {
c = i
return nil
},
}
err = r.Deserialize(m)
return
}
func toTypeIder(m map[string]interface{}) (tid typeIder, err error) {
var t []typeIder
r := &streams.Resolver{
AnyObjectCallback: func(i vocab.ObjectType) error {
t = append(t, i)
return nil
},
AnyLinkCallback: func(i vocab.LinkType) error {
t = append(t, i)
return nil
},
}
err = r.Deserialize(m)
if err != nil {
return
}
// TODO: Support more than one, which will enable creating multiple
// objects simultaneously.
if len(t) != 1 {
err = fmt.Errorf("too many object/links: %d", len(t))
return
}
tid = t[0]
return
}
func toAnyActivity(m map[string]interface{}) (o vocab.ActivityType, err error) {
r := &streams.Resolver{
AnyActivityCallback: func(i vocab.ActivityType) error {
o = i
return nil
},
}
err = r.Deserialize(m)
return
}