Use fastjson properly
This commit is contained in:
parent
c8d01274d3
commit
e26b856fcc
|
@ -6,6 +6,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// Activity Types
|
||||
|
@ -716,7 +718,12 @@ func ActivityNew(id ID, typ ActivityVocabularyType, ob Item) *Activity {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (a *Activity) UnmarshalJSON(data []byte) error {
|
||||
return loadActivity(data, a)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadActivity(val, a)
|
||||
}
|
||||
|
||||
// ToActivity
|
||||
|
|
24
actor.go
24
actor.go
|
@ -334,7 +334,12 @@ func (a *Actor) Clean() {
|
|||
}
|
||||
|
||||
func (a *Actor) UnmarshalJSON(data []byte) error {
|
||||
return loadActor(data, a)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadActor(val, a)
|
||||
}
|
||||
|
||||
func (a Actor) MarshalJSON() ([]byte, error) {
|
||||
|
@ -419,12 +424,17 @@ type Endpoints struct {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (e *Endpoints) UnmarshalJSON(data []byte) error {
|
||||
e.OauthAuthorizationEndpoint = JSONGetItem(data, "oauthAuthorizationEndpoint")
|
||||
e.OauthTokenEndpoint = JSONGetItem(data, "oauthTokenEndpoint")
|
||||
e.UploadMedia = JSONGetItem(data, "uploadMedia")
|
||||
e.ProvideClientKey = JSONGetItem(data, "provideClientKey")
|
||||
e.SignClientKey = JSONGetItem(data, "signClientKey")
|
||||
e.SharedInbox = JSONGetItem(data, "sharedInbox")
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.OauthAuthorizationEndpoint = JSONGetItem(val, "oauthAuthorizationEndpoint")
|
||||
e.OauthTokenEndpoint = JSONGetItem(val, "oauthTokenEndpoint")
|
||||
e.UploadMedia = JSONGetItem(val, "uploadMedia")
|
||||
e.ProvideClientKey = JSONGetItem(val, "provideClientKey")
|
||||
e.SignClientKey = JSONGetItem(val, "signClientKey")
|
||||
e.SharedInbox = JSONGetItem(val, "sharedInbox")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
const CollectionOfItems ActivityVocabularyType = "ItemCollection"
|
||||
|
@ -233,7 +235,12 @@ func (c Collection) Contains(r Item) bool {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (c *Collection) UnmarshalJSON(data []byte) error {
|
||||
return loadCollection(data, c)
|
||||
par := fastjson.Parser{}
|
||||
val, err := par.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadCollection(val, c)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"errors"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// CollectionPage is a Collection that contains a large number of items and when it becomes impractical
|
||||
|
@ -188,7 +190,12 @@ func (c CollectionPage) Contains(r Item) bool {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (c *CollectionPage) UnmarshalJSON(data []byte) error {
|
||||
return loadCollectionPage(data, c)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadCollectionPage(val, c)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
|
492
decoding_json.go
492
decoding_json.go
|
@ -1,12 +1,12 @@
|
|||
package activitypub
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
|
@ -26,58 +26,50 @@ var ItemTyperFunc TyperFn = GetItemByType
|
|||
// for a specific ActivityVocabularyType
|
||||
type TyperFn func(ActivityVocabularyType) (Item, error)
|
||||
|
||||
func JSONGetID(data []byte) ID {
|
||||
i := fastjson.GetString(data, "id")
|
||||
func JSONGetID(val *fastjson.Value) ID {
|
||||
i := val.Get("id").GetStringBytes()
|
||||
return ID(i)
|
||||
}
|
||||
|
||||
func JSONGetType(data []byte) ActivityVocabularyType {
|
||||
t := fastjson.GetBytes(data, "type")
|
||||
func JSONGetType(val *fastjson.Value) ActivityVocabularyType {
|
||||
t := val.Get("type").GetStringBytes()
|
||||
return ActivityVocabularyType(t)
|
||||
}
|
||||
|
||||
func JSONGetMimeType(data []byte, prop string) MimeType {
|
||||
t := fastjson.GetString(data, prop)
|
||||
func JSONGetMimeType(val *fastjson.Value, prop string) MimeType {
|
||||
t := val.Get(prop).GetStringBytes()
|
||||
return MimeType(t)
|
||||
}
|
||||
|
||||
func JSONGetInt(data []byte, prop string) int64 {
|
||||
if len(data) == 0 {
|
||||
return 0
|
||||
}
|
||||
val := fastjson.GetInt(data, prop)
|
||||
return int64(val)
|
||||
func JSONGetInt(val *fastjson.Value, prop string) int64 {
|
||||
i := val.Get(prop).GetInt64()
|
||||
return i
|
||||
}
|
||||
|
||||
func JSONGetFloat(data []byte, prop string) float64 {
|
||||
if len(data) == 0 {
|
||||
return 0
|
||||
}
|
||||
val := fastjson.GetFloat64(data, prop)
|
||||
return val
|
||||
func JSONGetFloat(val *fastjson.Value, prop string) float64 {
|
||||
f := val.Get(prop).GetFloat64()
|
||||
return f
|
||||
}
|
||||
|
||||
func JSONGetString(data []byte, prop string) string {
|
||||
val := fastjson.GetString(data, prop)
|
||||
return val
|
||||
func JSONGetString(val *fastjson.Value, prop string) string {
|
||||
s := val.Get(prop).GetStringBytes()
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func JSONGetBytes(data []byte, prop string) []byte {
|
||||
val := fastjson.GetBytes(data, prop)
|
||||
return val
|
||||
func JSONGetBytes(val *fastjson.Value, prop string) []byte {
|
||||
s := val.Get(prop).GetStringBytes()
|
||||
return s
|
||||
}
|
||||
|
||||
func JSONGetBoolean(data []byte, prop string) bool {
|
||||
val := fastjson.GetBool(data, prop)
|
||||
return val
|
||||
func JSONGetBoolean(val *fastjson.Value, prop string) bool {
|
||||
t, _ := val.Get(prop).Bool()
|
||||
return t
|
||||
}
|
||||
|
||||
func JSONGetNaturalLanguageField(data []byte, prop string) NaturalLanguageValues {
|
||||
func JSONGetNaturalLanguageField(val *fastjson.Value, prop string) NaturalLanguageValues {
|
||||
n := NaturalLanguageValues{}
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return nil
|
||||
if val == nil {
|
||||
return n
|
||||
}
|
||||
v := val.Get(prop)
|
||||
if v == nil {
|
||||
|
@ -105,44 +97,44 @@ func JSONGetNaturalLanguageField(data []byte, prop string) NaturalLanguageValues
|
|||
return n
|
||||
}
|
||||
|
||||
func JSONGetTime(data []byte, prop string) time.Time {
|
||||
func JSONGetTime(val *fastjson.Value, prop string) time.Time {
|
||||
t := time.Time{}
|
||||
if str := fastjson.GetBytes(data, prop); len(str) > 0 {
|
||||
if val == nil {
|
||||
return t
|
||||
}
|
||||
|
||||
if str := val.Get(prop).GetStringBytes(); len(str) > 0 {
|
||||
t.UnmarshalText(str)
|
||||
return t.UTC()
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func JSONGetDuration(data []byte, prop string) time.Duration {
|
||||
if str := fastjson.GetString(data, prop); len(str) > 0 {
|
||||
func JSONGetDuration(val *fastjson.Value, prop string) time.Duration {
|
||||
if str := val.Get(prop).GetStringBytes(); len(str) > 0 {
|
||||
// TODO(marius): this needs to be replaced to be compatible with xsd:duration
|
||||
d, _ := time.ParseDuration(str)
|
||||
d, _ := time.ParseDuration(string(str))
|
||||
return d
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func JSONGetPublicKey(data []byte, prop string) PublicKey {
|
||||
func JSONGetPublicKey(val *fastjson.Value, prop string) PublicKey {
|
||||
key := PublicKey{}
|
||||
key.UnmarshalJSON(JSONGetBytes(data, prop))
|
||||
key.UnmarshalJSON(JSONGetBytes(val, prop))
|
||||
return key
|
||||
}
|
||||
|
||||
func JSONGetStreams(data []byte, prop string) []ItemCollection {
|
||||
func JSONGetStreams(val *fastjson.Value, prop string) []ItemCollection {
|
||||
// TODO(marius)
|
||||
return nil
|
||||
}
|
||||
|
||||
func itemFn(data []byte) (Item, error) {
|
||||
if len(data) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
typ := JSONGetType(data)
|
||||
func itemFn(val *fastjson.Value) (Item, error) {
|
||||
typ := JSONGetType(val)
|
||||
if typ == "" {
|
||||
// try to see if it's an IRI
|
||||
if i, ok := asIRI(data); ok {
|
||||
if i, ok := asIRI(val); ok {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
|
@ -151,32 +143,81 @@ func itemFn(data []byte) (Item, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
p := reflect.PtrTo(reflect.TypeOf(i))
|
||||
if reflect.TypeOf(i).Implements(unmarshalerType) || p.Implements(unmarshalerType) {
|
||||
err = i.(json.Unmarshaler).UnmarshalJSON(data)
|
||||
}
|
||||
if reflect.TypeOf(i).Implements(textUnmarshalerType) || p.Implements(textUnmarshalerType) {
|
||||
err = i.(encoding.TextUnmarshaler).UnmarshalText(data)
|
||||
switch typ {
|
||||
case ObjectType, AudioType, DocumentType, EventType, ImageType, NoteType, PageType, VideoType:
|
||||
err = OnObject(i, func(ob *Object) error {
|
||||
return loadObject(val, ob)
|
||||
})
|
||||
case LinkType, MentionType:
|
||||
err = OnLink(i, func(l *Link) error {
|
||||
return loadLink(val, 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(i, func(act *Activity) error {
|
||||
return loadActivity(val, act)
|
||||
})
|
||||
case IntransitiveActivityType, ArriveType, TravelType:
|
||||
err = OnIntransitiveActivity(i, func(act *IntransitiveActivity) error {
|
||||
return loadIntransitiveActivity(val, act)
|
||||
})
|
||||
case ActorType, ArticleType, ApplicationType, GroupType, OrganizationType, PersonType, ServiceType:
|
||||
err = OnActor(i, func(a *Actor) error {
|
||||
return loadActor(val, a)
|
||||
})
|
||||
case CollectionType:
|
||||
err = OnCollection(i, func(c *Collection) error {
|
||||
return loadCollection(val, c)
|
||||
})
|
||||
case OrderedCollectionType:
|
||||
err = OnOrderedCollection(i, func(c *OrderedCollection) error {
|
||||
return loadOrderedCollection(val, c)
|
||||
})
|
||||
case CollectionPageType:
|
||||
err = OnCollectionPage(i, func(p *CollectionPage) error {
|
||||
return loadCollectionPage(val, p)
|
||||
})
|
||||
case OrderedCollectionPageType:
|
||||
err = OnOrderedCollectionPage(i, func(p *OrderedCollectionPage) error {
|
||||
return loadOrderedCollectionPage(val, p)
|
||||
})
|
||||
case PlaceType:
|
||||
err = OnPlace(i, func(p *Place) error {
|
||||
return loadPlace(val, p)
|
||||
})
|
||||
case ProfileType:
|
||||
err = OnProfile(i, func(p *Profile) error {
|
||||
return loadProfile(val, p)
|
||||
})
|
||||
case RelationshipType:
|
||||
err = OnRelationship(i, func(r *Relationship) error {
|
||||
return loadRelationship(val, r)
|
||||
})
|
||||
case TombstoneType:
|
||||
err = OnTombstone(i, func(t *Tombstone) error {
|
||||
return loadTombstone(val, t)
|
||||
})
|
||||
case QuestionType:
|
||||
err = OnQuestion(i, func(q *Question) error {
|
||||
return loadQuestion(val, q)
|
||||
})
|
||||
}
|
||||
|
||||
if !NotEmpty(i) {
|
||||
return nil, nil
|
||||
}
|
||||
return i, err
|
||||
}
|
||||
|
||||
func JSONUnmarshalToItem(data []byte) Item {
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
func JSONUnmarshalToItem(val *fastjson.Value) Item {
|
||||
if ItemTyperFunc == nil {
|
||||
return nil
|
||||
}
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var i Item
|
||||
var (
|
||||
i Item
|
||||
err error
|
||||
)
|
||||
switch val.Type() {
|
||||
case fastjson.TypeArray:
|
||||
items := make(ItemCollection, 0)
|
||||
|
@ -185,7 +226,7 @@ func JSONUnmarshalToItem(data []byte) Item {
|
|||
// NOTE(marius): I'm sure that using v.String here slows us down and undoes any benefits that fastjson
|
||||
// might bring
|
||||
v.Object()
|
||||
it, err = itemFn([]byte(v.String()))
|
||||
it, err = itemFn(v)
|
||||
if it != nil && err == nil {
|
||||
items.Append(it)
|
||||
}
|
||||
|
@ -198,9 +239,9 @@ func JSONUnmarshalToItem(data []byte) Item {
|
|||
i = items
|
||||
}
|
||||
case fastjson.TypeObject:
|
||||
i, err = itemFn(data)
|
||||
i, err = itemFn(val)
|
||||
case fastjson.TypeString:
|
||||
if iri, ok := asIRI(data); ok {
|
||||
if iri, ok := asIRI(val); ok {
|
||||
// try to see if it's an IRI
|
||||
i = iri
|
||||
}
|
||||
|
@ -211,39 +252,33 @@ func JSONUnmarshalToItem(data []byte) Item {
|
|||
return i
|
||||
}
|
||||
|
||||
func asIRI(val []byte) (IRI, bool) {
|
||||
if len(val) == 0 {
|
||||
func asIRI(val *fastjson.Value) (IRI, bool) {
|
||||
if val == nil {
|
||||
return NilIRI, true
|
||||
}
|
||||
val = bytes.Trim(val, string('"'))
|
||||
u, err := url.ParseRequestURI(string(val))
|
||||
s := strings.Trim(val.String(), `"`)
|
||||
u, err := url.ParseRequestURI(s)
|
||||
if err == nil && len(u.Scheme) > 0 && len(u.Host) > 0 {
|
||||
// try to see if it's an IRI
|
||||
return IRI(val), true
|
||||
return IRI(s), true
|
||||
}
|
||||
return EmptyIRI, false
|
||||
}
|
||||
|
||||
func JSONGetItem(data []byte, prop string) Item {
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
val = val.Get(prop)
|
||||
if val == nil {
|
||||
func JSONGetItem(val *fastjson.Value, prop string) Item {
|
||||
if val = val.Get(prop); val == nil {
|
||||
return nil
|
||||
}
|
||||
switch val.Type() {
|
||||
case fastjson.TypeString:
|
||||
if i, ok := asIRI(val.GetStringBytes()); ok {
|
||||
if i, ok := asIRI(val); ok {
|
||||
// try to see if it's an IRI
|
||||
return i
|
||||
}
|
||||
case fastjson.TypeArray:
|
||||
return JSONGetItems(data, prop)
|
||||
return JSONGetItems(val, prop)
|
||||
case fastjson.TypeObject:
|
||||
return JSONUnmarshalToItem(val.GetStringBytes())
|
||||
return JSONUnmarshalToItem(val)
|
||||
case fastjson.TypeNumber:
|
||||
fallthrough
|
||||
case fastjson.TypeNull:
|
||||
|
@ -254,12 +289,7 @@ func JSONGetItem(data []byte, prop string) Item {
|
|||
return nil
|
||||
}
|
||||
|
||||
func JSONGetURIItem(data []byte, prop string) Item {
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
func JSONGetURIItem(val *fastjson.Value, prop string) Item {
|
||||
v := val.Get(prop)
|
||||
if v == nil {
|
||||
return nil
|
||||
|
@ -267,24 +297,15 @@ func JSONGetURIItem(data []byte, prop string) Item {
|
|||
|
||||
switch v.Type() {
|
||||
case fastjson.TypeObject:
|
||||
return JSONGetItem(data, prop)
|
||||
return JSONGetItem(val, prop)
|
||||
case fastjson.TypeArray:
|
||||
it := make(ItemCollection, 0)
|
||||
for _, ob := range v.GetArray() {
|
||||
value := ob.GetStringBytes()
|
||||
if i, ok := asIRI(value); ok {
|
||||
it.Append(i)
|
||||
continue
|
||||
}
|
||||
i, err := ItemTyperFunc(JSONGetType(value))
|
||||
for _, val := range v.GetArray() {
|
||||
i, err := itemFn(val)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if err = i.(json.Unmarshaler).UnmarshalJSON(value); err != nil {
|
||||
continue
|
||||
}
|
||||
it.Append(i)
|
||||
|
||||
}
|
||||
return it
|
||||
case fastjson.TypeString:
|
||||
|
@ -294,32 +315,24 @@ func JSONGetURIItem(data []byte, prop string) Item {
|
|||
return nil
|
||||
}
|
||||
|
||||
func JSONGetItems(data []byte, prop string) ItemCollection {
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
p := fastjson.Parser{}
|
||||
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
val = val.Get(prop)
|
||||
func JSONGetItems(val *fastjson.Value, prop string) ItemCollection {
|
||||
if val == nil {
|
||||
return nil
|
||||
}
|
||||
if val = val.Get(prop); val == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
it := make(ItemCollection, 0)
|
||||
switch val.Type() {
|
||||
case fastjson.TypeArray:
|
||||
for _, v := range val.GetArray() {
|
||||
if i, err := itemFn([]byte(v.String())); i != nil && err == nil {
|
||||
if i, err := itemFn(v); i != nil && err == nil {
|
||||
it.Append(i)
|
||||
}
|
||||
}
|
||||
case fastjson.TypeObject:
|
||||
if i := JSONGetItem(data, prop); i != nil {
|
||||
if i := JSONGetItem(val, prop); i != nil {
|
||||
it.Append(i)
|
||||
}
|
||||
case fastjson.TypeString:
|
||||
|
@ -333,14 +346,14 @@ func JSONGetItems(data []byte, prop string) ItemCollection {
|
|||
return it
|
||||
}
|
||||
|
||||
func JSONGetLangRefField(data []byte, prop string) LangRef {
|
||||
val := fastjson.GetString(data, prop)
|
||||
return LangRef(val)
|
||||
func JSONGetLangRefField(val *fastjson.Value, prop string) LangRef {
|
||||
s := val.Get(prop).GetStringBytes()
|
||||
return LangRef(s)
|
||||
}
|
||||
|
||||
func JSONGetIRI(data []byte, prop string) IRI {
|
||||
val := fastjson.GetString(data, prop)
|
||||
return IRI(val)
|
||||
func JSONGetIRI(val *fastjson.Value, prop string) IRI {
|
||||
s := val.Get(prop).GetStringBytes()
|
||||
return IRI(s)
|
||||
}
|
||||
|
||||
// UnmarshalJSON tries to detect the type of the object in the json data and then outputs a matching
|
||||
|
@ -349,7 +362,10 @@ func UnmarshalJSON(data []byte) (Item, error) {
|
|||
if ItemTyperFunc == nil {
|
||||
ItemTyperFunc = GetItemByType
|
||||
}
|
||||
return JSONUnmarshalToItem(data), nil
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
|
||||
return JSONUnmarshalToItem(val), err
|
||||
}
|
||||
|
||||
func GetItemByType(typ ActivityVocabularyType) (Item, error) {
|
||||
|
@ -471,8 +487,8 @@ func GetItemByType(typ ActivityVocabularyType) (Item, error) {
|
|||
return nil, fmt.Errorf("empty ActivityStreams type")
|
||||
}
|
||||
|
||||
func JSONGetActorEndpoints(data []byte, prop string) *Endpoints {
|
||||
str := fastjson.GetBytes(data, prop)
|
||||
func JSONGetActorEndpoints(val *fastjson.Value, prop string) *Endpoints {
|
||||
str := val.Get(prop).GetStringBytes()
|
||||
|
||||
var e *Endpoints
|
||||
if len(str) > 0 {
|
||||
|
@ -483,204 +499,204 @@ func JSONGetActorEndpoints(data []byte, prop string) *Endpoints {
|
|||
return e
|
||||
}
|
||||
|
||||
func loadObject(data []byte, o *Object) error {
|
||||
func loadObject(val *fastjson.Value, o *Object) error {
|
||||
if ItemTyperFunc == nil {
|
||||
ItemTyperFunc = GetItemByType
|
||||
}
|
||||
o.ID = JSONGetID(data)
|
||||
o.Type = JSONGetType(data)
|
||||
o.Name = JSONGetNaturalLanguageField(data, "name")
|
||||
o.Content = JSONGetNaturalLanguageField(data, "content")
|
||||
o.Summary = JSONGetNaturalLanguageField(data, "summary")
|
||||
o.Context = JSONGetItem(data, "context")
|
||||
o.URL = JSONGetURIItem(data, "url")
|
||||
o.MediaType = JSONGetMimeType(data, "mediaType")
|
||||
o.Generator = JSONGetItem(data, "generator")
|
||||
o.AttributedTo = JSONGetItem(data, "attributedTo")
|
||||
o.Attachment = JSONGetItem(data, "attachment")
|
||||
o.Location = JSONGetItem(data, "location")
|
||||
o.Published = JSONGetTime(data, "published")
|
||||
o.StartTime = JSONGetTime(data, "startTime")
|
||||
o.EndTime = JSONGetTime(data, "endTime")
|
||||
o.Duration = JSONGetDuration(data, "duration")
|
||||
o.Icon = JSONGetItem(data, "icon")
|
||||
o.Preview = JSONGetItem(data, "preview")
|
||||
o.Image = JSONGetItem(data, "image")
|
||||
o.Updated = JSONGetTime(data, "updated")
|
||||
o.InReplyTo = JSONGetItem(data, "inReplyTo")
|
||||
o.To = JSONGetItems(data, "to")
|
||||
o.Audience = JSONGetItems(data, "audience")
|
||||
o.Bto = JSONGetItems(data, "bto")
|
||||
o.CC = JSONGetItems(data, "cc")
|
||||
o.BCC = JSONGetItems(data, "bcc")
|
||||
o.Replies = JSONGetItem(data, "replies")
|
||||
o.Tag = JSONGetItems(data, "tag")
|
||||
o.Likes = JSONGetItem(data, "likes")
|
||||
o.Shares = JSONGetItem(data, "shares")
|
||||
o.Source = GetAPSource(data)
|
||||
o.ID = JSONGetID(val)
|
||||
o.Type = JSONGetType(val)
|
||||
o.Name = JSONGetNaturalLanguageField(val, "name")
|
||||
o.Content = JSONGetNaturalLanguageField(val, "content")
|
||||
o.Summary = JSONGetNaturalLanguageField(val, "summary")
|
||||
o.Context = JSONGetItem(val, "context")
|
||||
o.URL = JSONGetURIItem(val, "url")
|
||||
o.MediaType = JSONGetMimeType(val, "mediaType")
|
||||
o.Generator = JSONGetItem(val, "generator")
|
||||
o.AttributedTo = JSONGetItem(val, "attributedTo")
|
||||
o.Attachment = JSONGetItem(val, "attachment")
|
||||
o.Location = JSONGetItem(val, "location")
|
||||
o.Published = JSONGetTime(val, "published")
|
||||
o.StartTime = JSONGetTime(val, "startTime")
|
||||
o.EndTime = JSONGetTime(val, "endTime")
|
||||
o.Duration = JSONGetDuration(val, "duration")
|
||||
o.Icon = JSONGetItem(val, "icon")
|
||||
o.Preview = JSONGetItem(val, "preview")
|
||||
o.Image = JSONGetItem(val, "image")
|
||||
o.Updated = JSONGetTime(val, "updated")
|
||||
o.InReplyTo = JSONGetItem(val, "inReplyTo")
|
||||
o.To = JSONGetItems(val, "to")
|
||||
o.Audience = JSONGetItems(val, "audience")
|
||||
o.Bto = JSONGetItems(val, "bto")
|
||||
o.CC = JSONGetItems(val, "cc")
|
||||
o.BCC = JSONGetItems(val, "bcc")
|
||||
o.Replies = JSONGetItem(val, "replies")
|
||||
o.Tag = JSONGetItems(val, "tag")
|
||||
o.Likes = JSONGetItem(val, "likes")
|
||||
o.Shares = JSONGetItem(val, "shares")
|
||||
o.Source = GetAPSource(val)
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadIntransitiveActivity(data []byte, i *IntransitiveActivity) error {
|
||||
func loadIntransitiveActivity(val *fastjson.Value, i *IntransitiveActivity) error {
|
||||
OnObject(i, func(o *Object) error {
|
||||
return loadObject(data, o)
|
||||
return loadObject(val, o)
|
||||
})
|
||||
i.Actor = JSONGetItem(data, "actor")
|
||||
i.Target = JSONGetItem(data, "target")
|
||||
i.Result = JSONGetItem(data, "result")
|
||||
i.Origin = JSONGetItem(data, "origin")
|
||||
i.Instrument = JSONGetItem(data, "instrument")
|
||||
i.Actor = JSONGetItem(val, "actor")
|
||||
i.Target = JSONGetItem(val, "target")
|
||||
i.Result = JSONGetItem(val, "result")
|
||||
i.Origin = JSONGetItem(val, "origin")
|
||||
i.Instrument = JSONGetItem(val, "instrument")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadActivity(data []byte, a *Activity) error {
|
||||
func loadActivity(val *fastjson.Value, a *Activity) error {
|
||||
OnIntransitiveActivity(a, func(i *IntransitiveActivity) error {
|
||||
return loadIntransitiveActivity(data, i)
|
||||
return loadIntransitiveActivity(val, i)
|
||||
})
|
||||
a.Object = JSONGetItem(data, "object")
|
||||
a.Object = JSONGetItem(val, "object")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadQuestion(data []byte, q *Question) error {
|
||||
func loadQuestion(val *fastjson.Value, q *Question) error {
|
||||
OnIntransitiveActivity(q, func(i *IntransitiveActivity) error {
|
||||
return loadIntransitiveActivity(data, i)
|
||||
return loadIntransitiveActivity(val, i)
|
||||
})
|
||||
q.OneOf = JSONGetItem(data, "oneOf")
|
||||
q.AnyOf = JSONGetItem(data, "anyOf")
|
||||
q.Closed = JSONGetBoolean(data, "closed")
|
||||
q.OneOf = JSONGetItem(val, "oneOf")
|
||||
q.AnyOf = JSONGetItem(val, "anyOf")
|
||||
q.Closed = JSONGetBoolean(val, "closed")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadActor(data []byte, a *Actor) error {
|
||||
func loadActor(val *fastjson.Value, a *Actor) error {
|
||||
OnObject(a, func(o *Object) error {
|
||||
return loadObject(data, o)
|
||||
return loadObject(val, o)
|
||||
})
|
||||
a.PreferredUsername = JSONGetNaturalLanguageField(data, "preferredUsername")
|
||||
a.Followers = JSONGetItem(data, "followers")
|
||||
a.Following = JSONGetItem(data, "following")
|
||||
a.Inbox = JSONGetItem(data, "inbox")
|
||||
a.Outbox = JSONGetItem(data, "outbox")
|
||||
a.Liked = JSONGetItem(data, "liked")
|
||||
a.Endpoints = JSONGetActorEndpoints(data, "endpoints")
|
||||
a.Streams = JSONGetStreams(data, "streams")
|
||||
a.PublicKey = JSONGetPublicKey(data, "publicKey")
|
||||
a.PreferredUsername = JSONGetNaturalLanguageField(val, "preferredUsername")
|
||||
a.Followers = JSONGetItem(val, "followers")
|
||||
a.Following = JSONGetItem(val, "following")
|
||||
a.Inbox = JSONGetItem(val, "inbox")
|
||||
a.Outbox = JSONGetItem(val, "outbox")
|
||||
a.Liked = JSONGetItem(val, "liked")
|
||||
a.Endpoints = JSONGetActorEndpoints(val, "endpoints")
|
||||
a.Streams = JSONGetStreams(val, "streams")
|
||||
a.PublicKey = JSONGetPublicKey(val, "publicKey")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadCollection(data []byte, c *Collection) error {
|
||||
func loadCollection(val *fastjson.Value, c *Collection) error {
|
||||
OnObject(c, func(o *Object) error {
|
||||
return loadObject(data, o)
|
||||
return loadObject(val, o)
|
||||
})
|
||||
c.Current = JSONGetItem(data, "current")
|
||||
c.First = JSONGetItem(data, "first")
|
||||
c.Last = JSONGetItem(data, "last")
|
||||
c.TotalItems = uint(JSONGetInt(data, "totalItems"))
|
||||
c.Items = JSONGetItems(data, "items")
|
||||
c.Current = JSONGetItem(val, "current")
|
||||
c.First = JSONGetItem(val, "first")
|
||||
c.Last = JSONGetItem(val, "last")
|
||||
c.TotalItems = uint(JSONGetInt(val, "totalItems"))
|
||||
c.Items = JSONGetItems(val, "items")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadCollectionPage(data []byte, c *CollectionPage) error {
|
||||
func loadCollectionPage(val *fastjson.Value, c *CollectionPage) error {
|
||||
OnCollection(c, func(c *Collection) error {
|
||||
return loadCollection(data, c)
|
||||
return loadCollection(val, c)
|
||||
})
|
||||
c.Next = JSONGetItem(data, "next")
|
||||
c.Prev = JSONGetItem(data, "prev")
|
||||
c.PartOf = JSONGetItem(data, "partOf")
|
||||
c.Next = JSONGetItem(val, "next")
|
||||
c.Prev = JSONGetItem(val, "prev")
|
||||
c.PartOf = JSONGetItem(val, "partOf")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadOrderedCollection(data []byte, c *OrderedCollection) error {
|
||||
func loadOrderedCollection(val *fastjson.Value, c *OrderedCollection) error {
|
||||
OnObject(c, func(o *Object) error {
|
||||
return loadObject(data, o)
|
||||
return loadObject(val, o)
|
||||
})
|
||||
c.Current = JSONGetItem(data, "current")
|
||||
c.First = JSONGetItem(data, "first")
|
||||
c.Last = JSONGetItem(data, "last")
|
||||
c.TotalItems = uint(JSONGetInt(data, "totalItems"))
|
||||
c.OrderedItems = JSONGetItems(data, "orderedItems")
|
||||
c.Current = JSONGetItem(val, "current")
|
||||
c.First = JSONGetItem(val, "first")
|
||||
c.Last = JSONGetItem(val, "last")
|
||||
c.TotalItems = uint(JSONGetInt(val, "totalItems"))
|
||||
c.OrderedItems = JSONGetItems(val, "orderedItems")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadOrderedCollectionPage(data []byte, c *OrderedCollectionPage) error {
|
||||
func loadOrderedCollectionPage(val *fastjson.Value, c *OrderedCollectionPage) error {
|
||||
OnOrderedCollection(c, func(c *OrderedCollection) error {
|
||||
return loadOrderedCollection(data, c)
|
||||
return loadOrderedCollection(val, c)
|
||||
})
|
||||
c.Next = JSONGetItem(data, "next")
|
||||
c.Prev = JSONGetItem(data, "prev")
|
||||
c.PartOf = JSONGetItem(data, "partOf")
|
||||
c.StartIndex = uint(JSONGetInt(data, "startIndex"))
|
||||
c.Next = JSONGetItem(val, "next")
|
||||
c.Prev = JSONGetItem(val, "prev")
|
||||
c.PartOf = JSONGetItem(val, "partOf")
|
||||
c.StartIndex = uint(JSONGetInt(val, "startIndex"))
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadPlace(data []byte, p *Place) error {
|
||||
func loadPlace(val *fastjson.Value, p *Place) error {
|
||||
OnObject(p, func(o *Object) error {
|
||||
return loadObject(data, o)
|
||||
return loadObject(val, o)
|
||||
})
|
||||
p.Accuracy = JSONGetFloat(data, "accuracy")
|
||||
p.Altitude = JSONGetFloat(data, "altitude")
|
||||
p.Latitude = JSONGetFloat(data, "latitude")
|
||||
p.Longitude = JSONGetFloat(data, "longitude")
|
||||
p.Radius = JSONGetInt(data, "radius")
|
||||
p.Units = JSONGetString(data, "units")
|
||||
p.Accuracy = JSONGetFloat(val, "accuracy")
|
||||
p.Altitude = JSONGetFloat(val, "altitude")
|
||||
p.Latitude = JSONGetFloat(val, "latitude")
|
||||
p.Longitude = JSONGetFloat(val, "longitude")
|
||||
p.Radius = JSONGetInt(val, "radius")
|
||||
p.Units = JSONGetString(val, "units")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadProfile(data []byte, p *Profile) error {
|
||||
func loadProfile(val *fastjson.Value, p *Profile) error {
|
||||
OnObject(p, func(o *Object) error {
|
||||
return loadObject(data, o)
|
||||
return loadObject(val, o)
|
||||
})
|
||||
p.Describes = JSONGetItem(data, "describes")
|
||||
p.Describes = JSONGetItem(val, "describes")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadRelationship(data []byte, r *Relationship) error {
|
||||
func loadRelationship(val *fastjson.Value, r *Relationship) error {
|
||||
OnObject(r, func(o *Object) error {
|
||||
return loadObject(data, o)
|
||||
return loadObject(val, o)
|
||||
})
|
||||
r.Subject = JSONGetItem(data, "subject")
|
||||
r.Object = JSONGetItem(data, "object")
|
||||
r.Relationship = JSONGetItem(data, "relationship")
|
||||
r.Subject = JSONGetItem(val, "subject")
|
||||
r.Object = JSONGetItem(val, "object")
|
||||
r.Relationship = JSONGetItem(val, "relationship")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadTombstone(data []byte, t *Tombstone) error {
|
||||
func loadTombstone(val *fastjson.Value, t *Tombstone) error {
|
||||
OnObject(t, func(o *Object) error {
|
||||
return loadObject(data, o)
|
||||
return loadObject(val, o)
|
||||
})
|
||||
t.FormerType = ActivityVocabularyType(JSONGetString(data, "formerType"))
|
||||
t.Deleted = JSONGetTime(data, "deleted")
|
||||
t.FormerType = ActivityVocabularyType(JSONGetString(val, "formerType"))
|
||||
t.Deleted = JSONGetTime(val, "deleted")
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadLink(data []byte, l *Link) error {
|
||||
func loadLink(val *fastjson.Value, l *Link) error {
|
||||
if ItemTyperFunc == nil {
|
||||
ItemTyperFunc = GetItemByType
|
||||
}
|
||||
l.ID = JSONGetID(data)
|
||||
l.Type = JSONGetType(data)
|
||||
l.MediaType = JSONGetMimeType(data, "mediaType")
|
||||
l.Preview = JSONGetItem(data, "preview")
|
||||
h := JSONGetInt(data, "height")
|
||||
l.ID = JSONGetID(val)
|
||||
l.Type = JSONGetType(val)
|
||||
l.MediaType = JSONGetMimeType(val, "mediaType")
|
||||
l.Preview = JSONGetItem(val, "preview")
|
||||
h := JSONGetInt(val, "height")
|
||||
if h != 0 {
|
||||
l.Height = uint(h)
|
||||
}
|
||||
w := JSONGetInt(data, "width")
|
||||
w := JSONGetInt(val, "width")
|
||||
if w != 0 {
|
||||
l.Width = uint(w)
|
||||
}
|
||||
l.Name = JSONGetNaturalLanguageField(data, "name")
|
||||
hrefLang := JSONGetLangRefField(data, "hrefLang")
|
||||
l.Name = JSONGetNaturalLanguageField(val, "name")
|
||||
hrefLang := JSONGetLangRefField(val, "hrefLang")
|
||||
if len(hrefLang) > 0 {
|
||||
l.HrefLang = hrefLang
|
||||
}
|
||||
href := JSONGetURIItem(data, "href")
|
||||
href := JSONGetURIItem(val, "href")
|
||||
if href != nil {
|
||||
ll := href.GetLink()
|
||||
if len(ll) > 0 {
|
||||
l.Href = ll
|
||||
}
|
||||
}
|
||||
rel := JSONGetURIItem(data, "rel")
|
||||
rel := JSONGetURIItem(val, "rel")
|
||||
if rel != nil {
|
||||
rr := rel.GetLink()
|
||||
if len(rr) > 0 {
|
||||
|
|
|
@ -363,23 +363,23 @@ func TestUnmarshalJSON(t *testing.T) {
|
|||
First: IRI("https://federated.git/inbox?maxItems=100"),
|
||||
OrderedItems: ItemCollection{
|
||||
&Activity{
|
||||
ID: "https://federated.git/activities/07440c39-64b2-4492-89cf-f5c2872cf4ff",
|
||||
Type: CreateType,
|
||||
ID: "https://federated.git/activities/07440c39-64b2-4492-89cf-f5c2872cf4ff",
|
||||
Type: CreateType,
|
||||
AttributedTo: IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91"),
|
||||
To: ItemCollection{PublicNS},
|
||||
CC: ItemCollection{ IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91/followers") },
|
||||
Published: time.Date(2021,8,8, 16, 9, 5, 0, time.UTC),
|
||||
Actor: IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91"),
|
||||
Object: IRI("https://federated.git/objects/3eb69f77-3b08-4bf1-8760-c7333e2900c4"),
|
||||
To: ItemCollection{PublicNS},
|
||||
CC: ItemCollection{IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91/followers")},
|
||||
Published: time.Date(2021, 8, 8, 16, 9, 5, 0, time.UTC),
|
||||
Actor: IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91"),
|
||||
Object: IRI("https://federated.git/objects/3eb69f77-3b08-4bf1-8760-c7333e2900c4"),
|
||||
},
|
||||
&Activity{
|
||||
ID: "https://federated.git/activities/ab9a5511-cdb5-4585-8a48-775d1bf20121",
|
||||
Type: LikeType,
|
||||
ID: "https://federated.git/activities/ab9a5511-cdb5-4585-8a48-775d1bf20121",
|
||||
Type: LikeType,
|
||||
AttributedTo: IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91"),
|
||||
To: ItemCollection{PublicNS, IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91")},
|
||||
Published: time.Date(2021,8,8, 16, 9, 5, 0, time.UTC),
|
||||
Actor: IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91"),
|
||||
Object: IRI("https://federated.git/objects/3eb69f77-3b08-4bf1-8760-c7333e2900c4"),
|
||||
To: ItemCollection{PublicNS, IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91")},
|
||||
Published: time.Date(2021, 8, 8, 16, 9, 5, 0, time.UTC),
|
||||
Actor: IRI("https://federated.git/actors/b1757243-080a-49dc-b832-42905d554b91"),
|
||||
Object: IRI("https://federated.git/objects/3eb69f77-3b08-4bf1-8760-c7333e2900c4"),
|
||||
},
|
||||
},
|
||||
TotalItems: 2,
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// IntransitiveActivity Instances of IntransitiveActivity are a subtype of Activity representing intransitive actions.
|
||||
|
@ -177,7 +179,12 @@ func (i IntransitiveActivity) IsCollection() bool {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (i *IntransitiveActivity) UnmarshalJSON(data []byte) error {
|
||||
return loadIntransitiveActivity(data, i)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadIntransitiveActivity(val, i)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
|
10
iri.go
10
iri.go
|
@ -156,18 +156,18 @@ func (i *IRIs) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
p := fastjson.Parser{}
|
||||
value, err := p.ParseBytes(data)
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch value.Type() {
|
||||
switch val.Type() {
|
||||
case fastjson.TypeString:
|
||||
if iri, ok := asIRI(value.GetStringBytes()); ok && len(iri) > 0 {
|
||||
if iri, ok := asIRI(val); ok && len(iri) > 0 {
|
||||
*i = append(*i, iri)
|
||||
}
|
||||
case fastjson.TypeArray:
|
||||
for _, v := range value.GetArray() {
|
||||
if iri, ok := asIRI(v.GetStringBytes()); ok && len(iri) > 0 {
|
||||
for _, v := range val.GetArray() {
|
||||
if iri, ok := asIRI(v); ok && len(iri) > 0 {
|
||||
*i = append(*i, iri)
|
||||
}
|
||||
}
|
||||
|
|
9
link.go
9
link.go
|
@ -3,6 +3,8 @@ package activitypub
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
var LinkTypes = ActivityVocabularyTypes{
|
||||
|
@ -104,7 +106,12 @@ func (l Link) MarshalJSON() ([]byte, error) {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (l *Link) UnmarshalJSON(data []byte) error {
|
||||
return loadLink(data, l)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadLink(val, l)
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
||||
|
|
23
object.go
23
object.go
|
@ -280,7 +280,12 @@ func (o Object) IsCollection() bool {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (o *Object) UnmarshalJSON(data []byte) error {
|
||||
return loadObject(data, o)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadObject(val, o)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
@ -478,13 +483,16 @@ type Source struct {
|
|||
}
|
||||
|
||||
// GetAPSource
|
||||
func GetAPSource(data []byte) Source {
|
||||
func GetAPSource(val *fastjson.Value) Source {
|
||||
s := Source{}
|
||||
if val == nil {
|
||||
return s
|
||||
}
|
||||
|
||||
if contBytes := fastjson.GetBytes(data, "source", "content"); len(contBytes) > 0 {
|
||||
if contBytes := val.Get("source", "content").GetStringBytes(); len(contBytes) > 0 {
|
||||
s.Content.UnmarshalJSON(contBytes)
|
||||
}
|
||||
if mimeBytes := fastjson.GetBytes(data, "source", "mediaType"); len(mimeBytes) > 0 {
|
||||
if mimeBytes := val.Get("source", "mediaType").GetStringBytes(); len(mimeBytes) > 0 {
|
||||
s.MediaType.UnmarshalJSON(mimeBytes)
|
||||
}
|
||||
|
||||
|
@ -493,7 +501,12 @@ func GetAPSource(data []byte) Source {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (s *Source) UnmarshalJSON(data []byte) error {
|
||||
*s = GetAPSource(data)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*s = GetAPSource(val)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
func TestObjectNew(t *testing.T) {
|
||||
|
@ -471,7 +473,10 @@ func TestSource_UnmarshalJSON(t *testing.T) {
|
|||
func TestGetAPSource(t *testing.T) {
|
||||
data := []byte(`{"source": {"content": "test", "mediaType": "text/plain" }}`)
|
||||
|
||||
a := GetAPSource(data)
|
||||
|
||||
par := fastjson.Parser{}
|
||||
val, _ := par.ParseBytes(data)
|
||||
a := GetAPSource(val)
|
||||
|
||||
if a.Content.First().String() != "test" {
|
||||
t.Errorf("Content didn't match test value. Received %q, expecting %q", a.Content, "test")
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// OrderedCollection is a subtype of Collection in which members of the logical
|
||||
|
@ -229,7 +231,12 @@ func (o *OrderedCollection) Append(ob Item) error {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (o *OrderedCollection) UnmarshalJSON(data []byte) error {
|
||||
return loadOrderedCollection(data, o)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadOrderedCollection(val, o)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"errors"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// OrderedCollectionPage type extends from both CollectionPage and OrderedCollection.
|
||||
|
@ -191,7 +193,12 @@ func (o OrderedCollectionPage) Contains(r Item) bool {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (o *OrderedCollectionPage) UnmarshalJSON(data []byte) error {
|
||||
return loadOrderedCollectionPage(data, o)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadOrderedCollectionPage(val, o)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
|
9
place.go
9
place.go
|
@ -5,6 +5,8 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// Place represents a logical or physical location. See 5.3 Representing Places for additional information.
|
||||
|
@ -153,7 +155,12 @@ func (p Place) GetID() ID {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (p *Place) UnmarshalJSON(data []byte) error {
|
||||
return loadPlace(data, p)
|
||||
par := fastjson.Parser{}
|
||||
val, err := par.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadPlace(val, p)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// Profile a Profile is a content object that describes another Object,
|
||||
|
@ -139,7 +141,12 @@ func (p Profile) GetID() ID {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (p *Profile) UnmarshalJSON(data []byte) error {
|
||||
return loadProfile(data, p)
|
||||
par := fastjson.Parser{}
|
||||
val, err := par.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadProfile(val, p)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"errors"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// Question represents a question being asked. Question objects are an extension of IntransitiveActivity.
|
||||
|
@ -164,7 +166,12 @@ func (q Question) IsCollection() bool {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (q *Question) UnmarshalJSON(data []byte) error {
|
||||
return loadQuestion(data, q)
|
||||
p := fastjson.Parser{}
|
||||
val, err := p.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadQuestion(val, q)
|
||||
}
|
||||
|
||||
func (q Question) MarshalJSON() ([]byte, error) {
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// Relationship describes a relationship between two individuals.
|
||||
|
@ -149,7 +151,12 @@ func (r Relationship) GetID() ID {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (r *Relationship) UnmarshalJSON(data []byte) error {
|
||||
return loadRelationship(data, r)
|
||||
par := fastjson.Parser{}
|
||||
val, err := par.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadRelationship(val, r)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/valyala/fastjson"
|
||||
)
|
||||
|
||||
// Tombstone a Tombstone represents a content object that has been deleted.
|
||||
|
@ -141,7 +143,12 @@ func (t Tombstone) GetID() ID {
|
|||
|
||||
// UnmarshalJSON
|
||||
func (t *Tombstone) UnmarshalJSON(data []byte) error {
|
||||
return loadTombstone(data, t)
|
||||
par := fastjson.Parser{}
|
||||
val, err := par.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return loadTombstone(val, t)
|
||||
}
|
||||
|
||||
// MarshalJSON
|
||||
|
|
Reference in a new issue