Changes
8 changed files (+182/-180)
-
-
@@ -7,7 +7,7 @@ import ("time" "unsafe" "github.com/buger/jsonparser" "github.com/valyala/fastjson" ) // CanReceiveActivities Types
-
@@ -195,20 +195,14 @@ type PublicKey struct {} func (p *PublicKey) UnmarshalJSON(data []byte) error { if id, err := jsonparser.GetString(data, "id"); err == nil { if id := fastjson.GetString(data, "id"); len(id) > 0 { p.ID = ID(id) } else { return err } if o, err := jsonparser.GetString(data, "owner"); err == nil { if o := fastjson.GetString(data, "owner"); len(o) > 0 { p.Owner = IRI(o) } else { return err } if pub, err := jsonparser.GetString(data, "publicKeyPem"); err == nil { if pub := fastjson.GetString(data, "publicKeyPem"); len(pub) > 0 { p.PublicKeyPem = pub } else { return err } return nil }
-
-
-
@@ -7,10 +7,9 @@ import ("fmt" "net/url" "reflect" "strconv" "time" "github.com/buger/jsonparser" "github.com/valyala/fastjson" ) var (
-
@@ -28,26 +27,17 @@ var ItemTyperFunc TyperFn = GetItemByTypetype TyperFn func(ActivityVocabularyType) (Item, error) func JSONGetID(data []byte) ID { i, err := jsonparser.GetString(data, "id") if err != nil { return "" } i := fastjson.GetString(data, "id") return ID(i) } func JSONGetType(data []byte) ActivityVocabularyType { t, err := jsonparser.GetString(data, "type") if err != nil { return "" } t := fastjson.GetBytes(data, "type") return ActivityVocabularyType(t) } func JSONGetMimeType(data []byte, prop string) MimeType { t, err := jsonparser.GetString(data, prop) if err != nil { return "" } t := fastjson.GetString(data, prop) return MimeType(t) }
-
@@ -55,73 +45,59 @@ func JSONGetInt(data []byte, prop string) int64 {if len(data) == 0 { return 0 } val, err := jsonparser.GetInt(data, prop) if err != nil { // try to load integers encapsulated in quotes if sn, err := jsonparser.GetString(data, prop); err == nil { val, _ = strconv.ParseInt(sn, 10, 64) } } return val val := fastjson.GetInt(data, prop) return int64(val) } func JSONGetFloat(data []byte, prop string) float64 { if len(data) == 0 { return 0 } val, err := jsonparser.GetFloat(data, prop) if err != nil { // try to load floats encapsulated in quotes if sn, err := jsonparser.GetString(data, prop); err == nil { val, _ = strconv.ParseFloat(sn, 64) } } val := fastjson.GetFloat64(data, prop) return val } func JSONGetString(data []byte, prop string) string { val, err := jsonparser.GetString(data, prop) if err != nil { } val := fastjson.GetString(data, prop) return val } func JSONGetBytes(data []byte, prop string) []byte { val, _, _, err := jsonparser.Get(data, prop) if err != nil { } val := fastjson.GetBytes(data, prop) return val } func JSONGetBoolean(data []byte, prop string) bool { val, err := jsonparser.GetBoolean(data, prop) if err != nil { } val := fastjson.GetBool(data, prop) return val } func JSONGetNaturalLanguageField(data []byte, prop string) NaturalLanguageValues { n := NaturalLanguageValues{} val, typ, _, err := jsonparser.Get(data, prop) if err != nil || val == nil { p := fastjson.Parser{} val, err := p.ParseBytes(data) if err != nil { return nil } switch typ { case jsonparser.Object: jsonparser.ObjectEach(val, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error { if dataType == jsonparser.String { l := LangRefValue{} if err := l.UnmarshalJSON(value); err == nil { if l.Ref != NilLangRef || len(l.Value) > 0 { n = append(n, l) } v := val.Get(prop) if v == nil { return nil } switch v.Type() { case fastjson.TypeObject: ob, _ := v.Object() ob.Visit(func(key []byte, v *fastjson.Value) { l := LangRefValue{} l.Ref = LangRef(key) if err := l.Value.UnmarshalJSON(v.GetStringBytes()); err == nil { if l.Ref != NilLangRef || len(l.Value) > 0 { n = append(n, l) } } return err }) case jsonparser.String: case fastjson.TypeString: l := LangRefValue{} if err := l.UnmarshalJSON(val); err == nil { if err := l.UnmarshalJSON(v.GetStringBytes()); err == nil { n = append(n, l) } }
-
@@ -131,15 +107,15 @@ func JSONGetNaturalLanguageField(data []byte, prop string) NaturalLanguageValuesfunc JSONGetTime(data []byte, prop string) time.Time { t := time.Time{} if str, _ := jsonparser.GetUnsafeString(data, prop); len(str) > 0 { t.UnmarshalText([]byte(str)) if str := fastjson.GetBytes(data, prop); len(str) > 0 { t.UnmarshalText(str) return t.UTC() } return t } func JSONGetDuration(data []byte, prop string) time.Duration { if str, _ := jsonparser.GetUnsafeString(data, prop); len(str) > 0 { if str := fastjson.GetString(data, prop); len(str) > 0 { // TODO(marius): this needs to be replaced to be compatible with xsd:duration d, _ := time.ParseDuration(str) return d
-
@@ -195,31 +171,32 @@ func JSONUnmarshalToItem(data []byte) Item {if ItemTyperFunc == nil { return nil } val, typ, _, err := jsonparser.Get(data) if err != nil || len(val) == 0 { p := fastjson.Parser{} val, err := p.ParseBytes(data) if err != nil { return nil } var i Item switch typ { case jsonparser.Array: switch val.Type() { case fastjson.TypeArray: items := make(ItemCollection, 0) jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { for _, v := range val.GetArray() { var it Item it, err = itemFn(value) it, err = itemFn(v.GetStringBytes()) if it != nil && err == nil { items.Append(it) } }) } if len(items) == 1 { i = items.First() } if len(items) > 1 { i = items } case jsonparser.Object: case fastjson.TypeObject: i, err = itemFn(data) case jsonparser.String: case fastjson.TypeString: if iri, ok := asIRI(data); ok { // try to see if it's an IRI i = iri
-
@@ -245,27 +222,28 @@ func asIRI(val []byte) (IRI, bool) {} func JSONGetItem(data []byte, prop string) Item { val, typ, _, err := jsonparser.Get(data, prop) p := fastjson.Parser{} val, err := p.ParseBytes(data) if err != nil { return nil } switch typ { case jsonparser.String: if i, ok := asIRI(val); ok { val = val.Get(prop) if val == nil { return nil } switch val.Type() { case fastjson.TypeString: if i, ok := asIRI(val.GetStringBytes()); ok { // try to see if it's an IRI return i } case jsonparser.Array: case fastjson.TypeArray: return JSONGetItems(data, prop) case jsonparser.Object: return JSONUnmarshalToItem(val) case jsonparser.Number: fallthrough case jsonparser.Boolean: case fastjson.TypeObject: return JSONUnmarshalToItem(val.GetStringBytes()) case fastjson.TypeNumber: fallthrough case jsonparser.Null: fallthrough case jsonparser.Unknown: case fastjson.TypeNull: fallthrough default: return nil
-
@@ -274,34 +252,40 @@ func JSONGetItem(data []byte, prop string) Item {} func JSONGetURIItem(data []byte, prop string) Item { val, typ, _, err := jsonparser.Get(data, prop) p := fastjson.Parser{} val, err := p.ParseBytes(data) if err != nil { return nil } v := val.Get(prop) if v == nil { return nil } switch typ { case jsonparser.Object: switch v.Type() { case fastjson.TypeObject: return JSONGetItem(data, prop) case jsonparser.Array: case fastjson.TypeArray: it := make(ItemCollection, 0) jsonparser.ArrayEach(val, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { for _, ob := range v.GetArray() { value := ob.GetStringBytes() if i, ok := asIRI(value); ok { it.Append(i) return continue } i, err := ItemTyperFunc(JSONGetType(value)) if err != nil { return continue } err = i.(json.Unmarshaler).UnmarshalJSON(value) if err != nil { return if err = i.(json.Unmarshaler).UnmarshalJSON(value); err != nil { continue } it.Append(i) }) } return it case jsonparser.String: return IRI(val) case fastjson.TypeString: return IRI(val.String()) } return nil
-
@@ -311,25 +295,32 @@ func JSONGetItems(data []byte, prop string) ItemCollection {if len(data) == 0 { return nil } val, typ, _, err := jsonparser.Get(data, prop) if err != nil || len(val) == 0 { p := fastjson.Parser{} v, err := p.ParseBytes(data) if err != nil { return nil } it := make(ItemCollection, 0) switch typ { case jsonparser.Array: jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { i, err := itemFn(value) if i != nil && err == nil { switch v.Type() { case fastjson.TypeArray: val := v.GetArray(prop) if len(val) == 0 { return nil } for _, v := range val { if i, err := itemFn(v.GetStringBytes()); i != nil && err == nil { it.Append(i) } }, prop) case jsonparser.Object: it.Append(JSONGetItem(data, prop)) case jsonparser.String: if len(val) > 0 { it.Append(IRI(val)) } case fastjson.TypeObject: if i := JSONGetItem(data, prop); i != nil { it.Append(i) } case fastjson.TypeString: if iri := v.GetStringBytes(); len(iri) > 0 { it.Append(IRI(iri)) } } if len(it) == 0 {
-
@@ -339,18 +330,12 @@ func JSONGetItems(data []byte, prop string) ItemCollection {} func JSONGetLangRefField(data []byte, prop string) LangRef { val, err := jsonparser.GetString(data, prop) if err != nil { return "" } val := fastjson.GetString(data, prop) return LangRef(val) } func JSONGetIRI(data []byte, prop string) IRI { val, err := jsonparser.GetString(data, prop) if err != nil { return "" } val := fastjson.GetString(data, prop) return IRI(val) }
-
@@ -483,12 +468,12 @@ func GetItemByType(typ ActivityVocabularyType) (Item, error) {} func JSONGetActorEndpoints(data []byte, prop string) *Endpoints { str, _ := jsonparser.GetUnsafeString(data, prop) str := fastjson.GetBytes(data, prop) var e *Endpoints if len(str) > 0 { e = &Endpoints{} e.UnmarshalJSON([]byte(str)) e.UnmarshalJSON(str) } return e
-
-
-
@@ -313,40 +313,49 @@ func TestJSONGetItemByType(t *testing.T) {} func TestUnmarshalJSON(t *testing.T) { type args struct { d []byte } tests := []struct { name string args args want Item name string data []byte want Item err error }{ { name: "empty", args: args{[]byte{'{', '}'}}, want: nil, err: nil, name: "empty", data: []byte{'{', '}'}, want: nil, err: nil, }, { name: "IRI", args: args{[]byte("\"http://example.com\"")}, want: IRI("http://example.com"), err: nil, name: "IRI", data: []byte(`"http://example.com"`), want: IRI("http://example.com"), err: nil, }, { name: "IRIs", args: args{[]byte(fmt.Sprintf("[%q, %q]", "http://example.com", "http://example.net"))}, name: "IRIs", data: []byte(fmt.Sprintf("[%q, %q]", "http://example.com", "http://example.net")), want: ItemCollection{ IRI("http://example.com"), IRI("http://example.net"), }, err: nil, }, { name: "object", data: []byte(`{"type":"Note"}`), want: &Object{Type: NoteType}, err: nil, }, { name: "activity", data: []byte(`{"type":"Like"}`), want: &Activity{Type: LikeType}, err: nil, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := UnmarshalJSON(tt.args.d) got, err := UnmarshalJSON(tt.data) if (err != nil && tt.err == nil) || (err == nil && tt.err != nil) { if !errors.Is(err, tt.err) { t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.err)
-
-
-
@@ -3,9 +3,10 @@ package activitypubimport ( "encoding/json" "fmt" "time" "git.sr.ht/~mariusor/go-xsd-duration" "github.com/go-ap/jsonld" "time" ) func writeComma(b *[]byte) {
-
-
-
@@ -4,6 +4,6 @@ go 1.13require ( git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20200411073322-f0bcc40f0bf2 github.com/buger/jsonparser v1.0.0 github.com/go-ap/jsonld v0.0.0-20200327122108-fafac2de2660 github.com/valyala/fastjson v1.6.3 )
-
-
-
@@ -2,10 +2,11 @@ package activitypubimport ( "fmt" "github.com/buger/jsonparser" "net/url" "path" "strings" "github.com/valyala/fastjson" ) const (
-
@@ -154,21 +155,22 @@ func (i *IRIs) UnmarshalJSON(data []byte) error {if i == nil { return nil } value, typ, _, err := jsonparser.Get(data) p := fastjson.Parser{} value, err := p.ParseBytes(data) if err != nil { return err } switch typ { case jsonparser.String: if iri, ok := asIRI(value); ok { switch value.Type() { case fastjson.TypeString: if iri, ok := asIRI(value.GetStringBytes()); ok && len(iri) > 0 { *i = append(*i, iri) } case jsonparser.Array: jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { if iri, ok := asIRI(value); ok { case fastjson.TypeArray: for _, v := range value.GetArray() { if iri, ok := asIRI(v.GetStringBytes()); ok && len(iri) > 0 { *i = append(*i, iri) } }) } } return nil }
-
-
-
@@ -6,7 +6,7 @@ import ("strconv" "strings" "github.com/buger/jsonparser" "github.com/valyala/fastjson" ) const NilLangRef LangRef = "-"
-
@@ -164,22 +164,23 @@ func (l LangRefValue) String() string {// UnmarshalJSON implements the JsonEncoder interface func (l *LangRefValue) UnmarshalJSON(data []byte) error { _, typ, _, err := jsonparser.Get(data) p := fastjson.Parser{} val, err := p.ParseBytes(data) if err != nil { l.Ref = NilLangRef l.Value = Content(unescape(data)) l.Value = unescape(data) return nil } switch typ { case jsonparser.Object: jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error { switch val.Type() { case fastjson.TypeObject: o, _ := val.Object() o.Visit(func(key []byte, v *fastjson.Value) { l.Ref = LangRef(key) l.Value = Content(unescape(value)) return err l.Value = unescape(v.GetStringBytes()) }) case jsonparser.String: case fastjson.TypeString: l.Ref = NilLangRef l.Value = Content(unescape(data)) l.Value = unescape(val.GetStringBytes()) } return nil
-
@@ -187,6 +188,8 @@ func (l *LangRefValue) UnmarshalJSON(data []byte) error {// UnmarshalText implements the TextEncoder interface func (l *LangRefValue) UnmarshalText(data []byte) error { l.Ref = NilLangRef l.Value = unescape(data) return nil }
-
@@ -277,7 +280,7 @@ func (c Content) Equals(other Content) bool {} func unescape(b []byte) []byte { // FIMXE(marius): I feel like I'm missing something really obvious about encoding/decoding from Json regarding // FIXME(marius): I feel like I'm missing something really obvious about encoding/decoding from Json regarding // escape characters, and that this function is just a hack. Be better future Marius, find the real problem! b = bytes.ReplaceAll(b, []byte{'\\', 'a'}, []byte{'\a'}) b = bytes.ReplaceAll(b, []byte{'\\', 'f'}, []byte{'\f'})
-
@@ -292,26 +295,33 @@ func unescape(b []byte) []byte {// UnmarshalJSON tries to load the NaturalLanguage array from the incoming json value func (n *NaturalLanguageValues) UnmarshalJSON(data []byte) error { val, typ, _, err := jsonparser.Get(data) p := fastjson.Parser{} val, err := p.ParseBytes(data) if err != nil { // try our luck if data contains an unquoted string n.Append(NilLangRef, Content(unescape(data))) n.Append(NilLangRef, unescape(data)) return nil } switch typ { case jsonparser.Object: jsonparser.ObjectEach(data, func(key []byte, val []byte, dataType jsonparser.ValueType, offset int) error { n.Append(LangRef(key), Content(unescape(val))) return err switch val.Type() { case fastjson.TypeObject: ob, _ := val.Object() ob.Visit(func(key []byte, v *fastjson.Value) { if dat := v.GetStringBytes(); len(dat) > 0 { n.Append(LangRef(key), unescape(dat)) } }) case jsonparser.String: n.Append(NilLangRef, Content(unescape(val))) case jsonparser.Array: jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { case fastjson.TypeString: if dat := val.GetStringBytes(); len(dat) > 0 { n.Append(NilLangRef, unescape(dat)) } case fastjson.TypeArray: for _, v := range val.GetArray() { l := LangRefValue{} l.UnmarshalJSON(value) n.Append(l.Ref, l.Value) }) l.UnmarshalJSON([]byte(v.String())) if len(l.Value) > 0 { n.Append(l.Ref, l.Value) } } } return nil
-
-
-
@@ -2,11 +2,12 @@ package activitypubimport ( "fmt" "github.com/buger/jsonparser" "reflect" "strings" "time" "unsafe" "github.com/valyala/fastjson" ) const (
-
@@ -480,10 +481,10 @@ type Source struct {func GetAPSource(data []byte) Source { s := Source{} if contBytes, _, _, err := jsonparser.Get(data, "source", "content"); err == nil { if contBytes := fastjson.GetBytes(data, "source", "content"); len(contBytes) > 0 { s.Content.UnmarshalJSON(contBytes) } if mimeBytes, _, _, err := jsonparser.Get(data, "source", "mediaType"); err == nil { if mimeBytes := fastjson.GetBytes(data, "source", "mediaType"); len(mimeBytes) > 0 { s.MediaType.UnmarshalJSON(mimeBytes) }
-