Adding upstream version 0.0~git20250501.71edba4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
c6ff472a6d
commit
c8085bda34
87 changed files with 24009 additions and 0 deletions
212
item.go
Normal file
212
item.go
Normal file
|
@ -0,0 +1,212 @@
|
|||
package activitypub
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Item struct
|
||||
type Item = ObjectOrLink
|
||||
|
||||
const (
|
||||
// EmptyIRI represents a zero length IRI
|
||||
EmptyIRI IRI = ""
|
||||
// NilIRI represents by convention an IRI which is nil
|
||||
// Its use is mostly to check if a property of an ActivityPub Item is nil
|
||||
NilIRI IRI = "-"
|
||||
|
||||
// EmptyID represents a zero length ID
|
||||
EmptyID = EmptyIRI
|
||||
// NilID represents by convention an ID which is nil, see details of NilIRI
|
||||
NilID = NilIRI
|
||||
)
|
||||
|
||||
func itemsNeedSwapping(i1, i2 Item) bool {
|
||||
if IsIRI(i1) && !IsIRI(i2) {
|
||||
return true
|
||||
}
|
||||
t1 := i1.GetType()
|
||||
t2 := i2.GetType()
|
||||
if ObjectTypes.Contains(t2) {
|
||||
return !ObjectTypes.Contains(t1)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ItemsEqual checks if it and with Items are equal
|
||||
func ItemsEqual(it, with Item) bool {
|
||||
if IsNil(it) || IsNil(with) {
|
||||
return IsNil(with) && IsNil(it)
|
||||
}
|
||||
if itemsNeedSwapping(it, with) {
|
||||
return ItemsEqual(with, it)
|
||||
}
|
||||
result := false
|
||||
if IsIRI(with) || IsIRI(it) {
|
||||
// NOTE(marius): I'm not sure this logic is sound:
|
||||
// if only one item is an IRI it should not be equal to the other even if it has the same ID
|
||||
result = it.GetLink().Equals(with.GetLink(), false)
|
||||
} else if IsItemCollection(it) {
|
||||
if !IsItemCollection(with) {
|
||||
return false
|
||||
}
|
||||
_ = OnItemCollection(it, func(c *ItemCollection) error {
|
||||
result = c.Equals(with)
|
||||
return nil
|
||||
})
|
||||
} else if IsObject(it) {
|
||||
_ = OnObject(it, func(i *Object) error {
|
||||
result = i.Equals(with)
|
||||
return nil
|
||||
})
|
||||
if ActivityTypes.Contains(with.GetType()) {
|
||||
_ = OnActivity(it, func(i *Activity) error {
|
||||
result = i.Equals(with)
|
||||
return nil
|
||||
})
|
||||
} else if ActorTypes.Contains(with.GetType()) {
|
||||
_ = OnActor(it, func(i *Actor) error {
|
||||
result = i.Equals(with)
|
||||
return nil
|
||||
})
|
||||
} else if it.IsCollection() {
|
||||
if it.GetType() == CollectionType {
|
||||
_ = OnCollection(it, func(c *Collection) error {
|
||||
result = c.Equals(with)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if it.GetType() == OrderedCollectionType {
|
||||
_ = OnOrderedCollection(it, func(c *OrderedCollection) error {
|
||||
result = c.Equals(with)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if it.GetType() == CollectionPageType {
|
||||
_ = OnCollectionPage(it, func(c *CollectionPage) error {
|
||||
result = c.Equals(with)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if it.GetType() == OrderedCollectionPageType {
|
||||
_ = OnOrderedCollectionPage(it, func(c *OrderedCollectionPage) error {
|
||||
result = c.Equals(with)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsItemCollection returns if the current Item interface holds a Collection
|
||||
func IsItemCollection(it LinkOrIRI) bool {
|
||||
_, ok := it.(ItemCollection)
|
||||
_, okP := it.(*ItemCollection)
|
||||
return ok || okP || IsIRIs(it)
|
||||
}
|
||||
|
||||
// IsIRI returns if the current Item interface holds an IRI
|
||||
func IsIRI(it LinkOrIRI) bool {
|
||||
_, okV := it.(IRI)
|
||||
_, okP := it.(*IRI)
|
||||
return okV || okP
|
||||
}
|
||||
|
||||
// IsIRIs returns if the current Item interface holds an IRI slice
|
||||
func IsIRIs(it LinkOrIRI) bool {
|
||||
_, okV := it.(IRIs)
|
||||
_, okP := it.(*IRIs)
|
||||
return okV || okP
|
||||
}
|
||||
|
||||
// IsLink returns if the current Item interface holds a Link
|
||||
func IsLink(it LinkOrIRI) bool {
|
||||
_, okV := it.(Link)
|
||||
_, okP := it.(*Link)
|
||||
return okV || okP
|
||||
}
|
||||
|
||||
// IsObject returns if the current Item interface holds an Object
|
||||
func IsObject(it LinkOrIRI) bool {
|
||||
switch ob := it.(type) {
|
||||
case Actor, *Actor,
|
||||
Object, *Object, Profile, *Profile, Place, *Place, Relationship, *Relationship, Tombstone, *Tombstone,
|
||||
Activity, *Activity, IntransitiveActivity, *IntransitiveActivity, Question, *Question,
|
||||
Collection, *Collection, CollectionPage, *CollectionPage,
|
||||
OrderedCollection, *OrderedCollection, OrderedCollectionPage, *OrderedCollectionPage:
|
||||
return ob != nil
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// IsNil checks if the object matching an ObjectOrLink interface is nil
|
||||
func IsNil(it LinkOrIRI) bool {
|
||||
if it == nil {
|
||||
return true
|
||||
}
|
||||
// This is the default if the argument can't be cast to Object, as is the case for an ItemCollection
|
||||
isNil := false
|
||||
if IsIRI(it) {
|
||||
isNil = len(it.GetLink()) == 0 || strings.EqualFold(it.GetLink().String(), NilIRI.String())
|
||||
} else if IsItemCollection(it) {
|
||||
if v, ok := it.(ItemCollection); ok {
|
||||
return v == nil
|
||||
}
|
||||
if v, ok := it.(*ItemCollection); ok {
|
||||
return v == nil
|
||||
}
|
||||
if v, ok := it.(IRIs); ok {
|
||||
return v == nil
|
||||
}
|
||||
if v, ok := it.(*IRIs); ok {
|
||||
return v == nil
|
||||
}
|
||||
} else if IsObject(it) {
|
||||
if ob, ok := it.(Item); ok {
|
||||
_ = OnObject(ob, func(o *Object) error {
|
||||
isNil = o == nil
|
||||
return nil
|
||||
})
|
||||
}
|
||||
} else if IsLink(it) {
|
||||
_ = OnLink(it, func(l *Link) error {
|
||||
isNil = l == nil
|
||||
return nil
|
||||
})
|
||||
} else {
|
||||
// NOTE(marius): we're not dealing with a type that we know about, so we use slow reflection
|
||||
// as we still care about the result
|
||||
v := reflect.ValueOf(it)
|
||||
isNil = v.Kind() == reflect.Pointer && v.IsNil()
|
||||
}
|
||||
return isNil
|
||||
}
|
||||
|
||||
func ErrorInvalidType[T Objects | Links | IRIs](received LinkOrIRI) error {
|
||||
return fmt.Errorf("unable to convert %T to %T", received, new(T))
|
||||
}
|
||||
|
||||
// OnItem runs function "fn" on the Item "it", with the benefit of destructuring "it" to individual
|
||||
// items if it's actually an ItemCollection or an object holding an ItemCollection
|
||||
//
|
||||
// It is expected that the caller handles the logic of dealing with different Item implementations
|
||||
// internally in "fn".
|
||||
func OnItem(it Item, fn func(Item) error) error {
|
||||
if it == nil {
|
||||
return nil
|
||||
}
|
||||
if !IsItemCollection(it) {
|
||||
return fn(it)
|
||||
}
|
||||
return OnItemCollection(it, func(col *ItemCollection) error {
|
||||
for _, it := range *col {
|
||||
if err := OnItem(it, fn); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue