Adding some Format methods for custom printing of objects

This commit is contained in:
mariusor 2022-05-25 13:46:03 +02:00
parent 5c59dccd55
commit 52ce087a26
No known key found for this signature in database
GPG key ID: DBF5E47F5DBC4D21
16 changed files with 361 additions and 1 deletions

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"strings"
"time"
@ -732,6 +733,24 @@ func (a *Activity) UnmarshalJSON(data []byte) error {
return loadActivity(val, a)
}
func fmtActivityProps(w io.Writer) func(*Activity) error {
return func(a *Activity) error {
if !IsNil(a.Object) {
io.WriteString(w, fmt.Sprintf(" object: %s", a.Object))
}
return OnIntransitiveActivity(a, fmtIntransitiveActivityProps(w))
}
}
func (a Activity) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] {", a, a.Type))
fmtActivityProps(s)(&a)
io.WriteString(s, " }")
}
}
// ToActivity
func ToActivity(it Item) (*Activity, error) {
switch i := it.(type) {

View file

@ -5,6 +5,7 @@ import (
"encoding/gob"
"encoding/json"
"fmt"
"io"
"reflect"
"time"
@ -413,6 +414,13 @@ func (a Actor) MarshalJSON() ([]byte, error) {
return nil, nil
}
func (a Actor) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { }", a, a.Type))
}
}
// Endpoints a json object which maps additional (typically server/domain-wide)
// endpoints which may be useful either for this actor or someone referencing this actor.
// This mapping may be nested inside the actor document as the value or may be a link to

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
"unsafe"
@ -314,6 +315,13 @@ func (c *Collection) GobDecode(data []byte) error {
return unmapCollectionProperties(mm, c)
}
func (c Collection) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { totalItems: %d }", c, c.Type, c.TotalItems))
}
}
// ToCollection
func ToCollection(it Item) (*Collection, error) {
switch i := it.(type) {

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
@ -410,3 +411,10 @@ func (c CollectionPage) Equals(with Item) bool {
})
return result
}
func (c CollectionPage) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { totalItems: %d }", c, c.Type, c.TotalItems))
}
}

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
"unsafe"
@ -341,3 +342,31 @@ func (i IntransitiveActivity) Equals(with Item) bool {
}
return result
}
func fmtIntransitiveActivityProps(w io.Writer) func(*IntransitiveActivity) error {
return func(ia *IntransitiveActivity) error {
if !IsNil(ia.Actor) {
io.WriteString(w, fmt.Sprintf(" actor: %s", ia.Actor))
}
if !IsNil(ia.Target) {
io.WriteString(w, fmt.Sprintf(" target: %s", ia.Target))
}
if !IsNil(ia.Result) {
io.WriteString(w, fmt.Sprintf(" result: %s", ia.Result))
}
if !IsNil(ia.Origin) {
io.WriteString(w, fmt.Sprintf(" origin: %s", ia.Origin))
}
if !IsNil(ia.Instrument) {
io.WriteString(w, fmt.Sprintf(" instrument: %s", ia.Instrument))
}
return OnObject(ia, fmtObjectProps(w))
}
}
func (i IntransitiveActivity) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { }", i, i.Type))
}
}

10
link.go
View file

@ -3,6 +3,9 @@ package activitypub
import (
"bytes"
"encoding/gob"
"fmt"
"io"
"github.com/valyala/fastjson"
)
@ -155,3 +158,10 @@ func (l *Link) GobDecode(data []byte) error {
}
return unmapLinkProperties(mm, l)
}
func (l Link) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { }", l, l.Type))
}
}

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"strconv"
"strings"
@ -134,6 +135,23 @@ func (n NaturalLanguageValues) MarshalText() ([]byte, error) {
return nil, nil
}
func (n NaturalLanguageValues) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'q':
io.WriteString(s, "[")
for _, nn := range n {
nn.Format(s, verb)
}
io.WriteString(s, "]")
case 'v':
io.WriteString(s, "[")
for _, nn := range n {
nn.Format(s, verb)
}
io.WriteString(s, "]")
}
}
// Append is syntactic sugar for resizing the NaturalLanguageValues map
// and appending an element
func (n *NaturalLanguageValues) Append(lang LangRef, value Content) error {
@ -165,6 +183,23 @@ func (l LangRefValue) String() string {
return fmt.Sprintf("%s[%s]", l.Value, l.Ref)
}
func (l LangRefValue) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'q':
if l.Ref == NilLangRef {
io.WriteString(s, string(l.Value))
} else {
io.WriteString(s, fmt.Sprintf("%q[%s]", l.Value, l.Ref))
}
case 'v':
if l.Ref == NilLangRef {
io.WriteString(s, fmt.Sprintf("%q", string(l.Value)))
} else {
io.WriteString(s, fmt.Sprintf("%q[%s]", string(l.Value), l.Ref))
}
}
}
// UnmarshalJSON decodes an incoming JSON document into the receiver object.
func (l *LangRefValue) UnmarshalJSON(data []byte) error {
p := fastjson.Parser{}
@ -368,6 +403,15 @@ func (c Content) Equals(other Content) bool {
return bytes.Equal(c, other)
}
func (c Content) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'q':
io.WriteString(s, string(c))
case 'v':
io.WriteString(s, fmt.Sprintf("%q", string(c)))
}
}
func unescape(b []byte) []byte {
// 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!

View file

@ -263,7 +263,7 @@ func TestNaturalLanguageValue_MarshalText(t *testing.T) {
if j == nil {
t.Errorf("Error marshaling: nil value returned")
}
expected := fmt.Sprintf("\"%s[%s]\"", nlv.Value, nlv.Ref)
expected := fmt.Sprintf("%s[%s]", nlv.Value, nlv.Ref)
if string(j) != expected {
t.Errorf("Wrong value: %s, expected %s", j, expected)
}

178
object.go
View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"strings"
"time"
@ -342,6 +343,183 @@ func (o *Object) GobDecode(data []byte) error {
return unmapObjectProperties(mm, o)
}
func fmtObjectProps(w io.Writer) func(*Object) error {
return func(o *Object) error {
if len(o.Name) > 0 {
n, _ := io.WriteString(w, fmt.Sprintf("%s: [%s]", "name", o.Name))
if n > 0 {
io.WriteString(w, ", ")
}
}
if len(o.Summary) > 0 {
n, _ := io.WriteString(w, fmt.Sprintf("%s: [%s]", "summary", o.Summary))
if n > 0 {
io.WriteString(w, ", ")
}
}
if len(o.Content) > 0 {
n, _ := io.WriteString(w, fmt.Sprintf("%s: [%s]", "content", o.Content))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Attachment) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "attachment", o.Attachment))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.AttributedTo) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "attributedTo", o.AttributedTo))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Audience) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "audience", o.Audience))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Context) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "context", o.Context))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Generator) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "generator", o.Generator))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Icon) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "icon", o.Icon))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Image) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "image", o.Image))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.InReplyTo) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "inReplyTo", o.InReplyTo))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Location) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "location", o.Location))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Preview) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "preview", o.Preview))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Replies) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "replies", o.Replies))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Tag) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "tag", o.Tag))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.URL) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "url", o.URL))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.To) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "to", o.To))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Bto) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "bto", o.Bto))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.CC) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "cc", o.CC))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.BCC) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "bcc", o.BCC))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !o.Published.IsZero() {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "published", o.Published))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !o.Updated.IsZero() {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "updated", o.Updated))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !o.StartTime.IsZero() {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "startTime", o.StartTime))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !o.EndTime.IsZero() {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "endTime", o.EndTime))
if n > 0 {
io.WriteString(w, ", ")
}
}
if o.Duration != 0 {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "duration", o.Duration))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Likes) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "likes", o.Likes))
if n > 0 {
io.WriteString(w, ", ")
}
}
if !IsNil(o.Shares) {
n, _ := io.WriteString(w, fmt.Sprintf("%s: %s", "shares", o.Shares))
if n > 0 {
io.WriteString(w, ", ")
}
}
return nil
}
}
func (o Object) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { ", o, o.Type))
fmtObjectProps(s)(&o)
io.WriteString(s, " }")
}
}
// Recipients performs recipient de-duplication on the Object's To, Bto, CC and BCC properties
func (o *Object) Recipients() ItemCollection {
var aud ItemCollection

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
"unsafe"
@ -483,3 +484,10 @@ func (o OrderedCollection) Equals(with Item) bool {
})
return result
}
func (o OrderedCollection) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { totalItems: %d }", o, o.Type, o.TotalItems))
}
}

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
@ -368,3 +369,10 @@ func (o OrderedCollectionPage) Equals(with Item) bool {
})
return result
}
func (o OrderedCollectionPage) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { totalItems: %d }", o, o.Type, o.TotalItems))
}
}

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
"unsafe"
@ -251,6 +252,13 @@ func (p *Place) Clean() {
p.Bto = nil
}
func (p Place) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { }", p, p.Type))
}
}
// ToPlace
func ToPlace(it Item) (*Place, error) {
switch i := it.(type) {

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
"unsafe"
@ -223,6 +224,13 @@ func (p *Profile) Clean() {
p.Bto = nil
}
func (p Profile) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { }", p, p.Type))
}
}
// ToProfile tries to convert the it Item to a Profile object
func ToProfile(it Item) (*Profile, error) {
switch i := it.(type) {

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
@ -228,6 +229,13 @@ func (q *Question) GobDecode(data []byte) error {
return unmapQuestionProperties(mm, q)
}
func (q Question) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { }", q, q.Type))
}
}
// QuestionNew initializes a Question activity
func QuestionNew(id ID) *Question {
q := Question{ID: id, Type: QuestionType}

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
"unsafe"
@ -240,6 +241,13 @@ func (r *Relationship) Clean() {
r.Bto = nil
}
func (r Relationship) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { }", r, r.Type))
}
}
// ToRelationship tries to convert the it Item to a Relationship object.
func ToRelationship(it Item) (*Relationship, error) {
switch i := it.(type) {

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/gob"
"fmt"
"io"
"reflect"
"time"
"unsafe"
@ -229,6 +230,13 @@ func (t *Tombstone) Clean() {
t.Bto = nil
}
func (t Tombstone) Format(s fmt.State, verb rune) {
switch verb {
case 's', 'v':
io.WriteString(s, fmt.Sprintf("%T[%s] { formerType: %q }", t, t.Type, t.FormerType))
}
}
// ToTombstone
func ToTombstone(it Item) (*Tombstone, error) {
switch i := it.(type) {