Migrate Typer and type-detection functions to vocab
This helps ensure that the code to detect specific ActivityStream types continues to live in the code-generation algorithms, reducing maintenance burdens.
このコミットが含まれているのは:
コミット
fb16747c4e
|
@ -308,7 +308,7 @@ func (f *federator) PostOutbox(c context.Context, w http.ResponseWriter, r *http
|
|||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
if !isActivityType(typer) {
|
||||
if !vocab.IsActivityType(typer) {
|
||||
actorIri, err := f.SocialAPI.ActorIRI(c, r)
|
||||
if err != nil {
|
||||
return true, err
|
||||
|
|
|
@ -125,7 +125,7 @@ func serveActivityPubObject(c context.Context, a Application, clock Clock, w htt
|
|||
return
|
||||
}
|
||||
addResponseHeaders(w.Header(), clock, b)
|
||||
if hasType(pObj, tombstone) {
|
||||
if vocab.HasTypeTombstone(pObj) {
|
||||
w.WriteHeader(http.StatusGone)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
|
|
@ -307,8 +307,7 @@ type PubObject interface {
|
|||
|
||||
// Typer is an object that has a type.
|
||||
type Typer interface {
|
||||
TypeLen() (l int)
|
||||
GetType(index int) (v interface{})
|
||||
vocab.Typer
|
||||
}
|
||||
|
||||
// typeIder is a Typer with additional generic capabilities.
|
||||
|
|
|
@ -208,7 +208,7 @@ func postToOutbox(c HttpClient, b []byte, to *url.URL, agent string, creds *cred
|
|||
func (f *federator) addNewIds(c context.Context, a vocab.ActivityType) {
|
||||
newId := f.App.NewId(c, a)
|
||||
a.SetId(newId)
|
||||
if hasType(a, create) {
|
||||
if vocab.HasTypeCreate(a) {
|
||||
for i := 0; i < a.ObjectLen(); i++ {
|
||||
if a.IsObject(i) {
|
||||
obj := a.GetObject(i)
|
||||
|
@ -2123,39 +2123,3 @@ func clearSensitiveFields(obj vocab.ObjectType) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Move this to vocab package.
|
||||
var activityTypes = []string{"Accept", "Add", "Announce", "Arrive", "Block", "Create", "Delete", "Dislike", "Flag", "Follow", "Ignore", "Invite", "Join", "Leave", "Like", "Listen", "Move", "Offer", "Question", "Reject", "Read", "Remove", "TentativeReject", "TentativeAccept", "Travel", "Undo", "Update", "View"}
|
||||
|
||||
const (
|
||||
tombstone = "Tombstone"
|
||||
create = "Create"
|
||||
)
|
||||
|
||||
func isActivityType(t Typer) bool {
|
||||
hasType := make(map[string]bool, 1)
|
||||
for i := 0; i < t.TypeLen(); i++ {
|
||||
v := t.GetType(i)
|
||||
if s, ok := v.(string); ok {
|
||||
hasType[s] = true
|
||||
}
|
||||
}
|
||||
for _, t := range activityTypes {
|
||||
if hasType[t] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hasType(t Typer, kind string) bool {
|
||||
for i := 0; i < t.TypeLen(); i++ {
|
||||
v := t.GetType(i)
|
||||
if s, ok := v.(string); ok {
|
||||
if s == kind {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1942,3 +1942,18 @@ func AnyURIValueTypeName() string {
|
|||
func IRIFuncs() []*FunctionDef {
|
||||
return []*FunctionDef{IriValueType.DeserializeFn, IriValueType.SerializeFn}
|
||||
}
|
||||
|
||||
func IsActivity(t *Type) bool {
|
||||
var recur func(t *Type) bool
|
||||
recur = func(t *Type) bool {
|
||||
for _, e := range t.Extends {
|
||||
if e == activityType {
|
||||
return true
|
||||
} else if recur(e) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
return recur(t)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/go-fed/activity/tools/defs"
|
||||
"go/format"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -44,6 +45,8 @@ func GenerateImplementations(types []*defs.Type, properties []*defs.PropertyType
|
|||
p.F = append(p.F, v.DeserializeFn, v.SerializeFn)
|
||||
}
|
||||
p.F = append(p.F, defs.IRIFuncs()...)
|
||||
p.F = append(p.F, generateHasTypeFuncs(types)...)
|
||||
p.I = append(p.I, generateTyperInterface())
|
||||
|
||||
// Add functions to resolve string 'name' into concrete types
|
||||
p.F = append(p.F, generateResolveObjectFunction(types))
|
||||
|
@ -60,6 +63,78 @@ func GenerateImplementations(types []*defs.Type, properties []*defs.PropertyType
|
|||
return format.Source([]byte(p.Generate()))
|
||||
}
|
||||
|
||||
func generateTyperInterface() *defs.InterfaceDef {
|
||||
return &defs.InterfaceDef{
|
||||
Typename: "Typer",
|
||||
Comment: "Typer supports common functions for determining an ActivityStream type",
|
||||
F: []*defs.FunctionDef{
|
||||
{
|
||||
Name: "TypeLen",
|
||||
Return: []*defs.FunctionVarDef{{Name: "l", Type: "int"}},
|
||||
},
|
||||
{
|
||||
Name: "GetType",
|
||||
Args: []*defs.FunctionVarDef{{Name: "index", Type: "int"}},
|
||||
Return: []*defs.FunctionVarDef{{Name: "v", Type: "interface{}"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func generateHasTypeFuncs(types []*defs.Type) (f []*defs.FunctionDef) {
|
||||
var activityTypes []string
|
||||
for _, t := range types {
|
||||
t := t
|
||||
if defs.IsActivity(t) {
|
||||
activityTypes = append(activityTypes, t.Name)
|
||||
}
|
||||
f = append(f, &defs.FunctionDef{
|
||||
Name: fmt.Sprintf("HasType%s", t.Name),
|
||||
Comment: fmt.Sprintf("HasType%s returns true if the Typer has a type of %s.", t.Name, t.Name),
|
||||
Args: []*defs.FunctionVarDef{{Name: "t", Type: "Typer"}},
|
||||
Return: []*defs.FunctionVarDef{{Name: "b", Type: "bool"}},
|
||||
Body: func() string {
|
||||
var b bytes.Buffer
|
||||
b.WriteString("for i := 0; i < t.TypeLen(); i++ {\n")
|
||||
b.WriteString("v := t.GetType(i)\n")
|
||||
b.WriteString("if s, ok := v.(string); ok {\n")
|
||||
b.WriteString(fmt.Sprintf("if s == \"%s\" {\n", t.Name))
|
||||
b.WriteString("return true\n")
|
||||
b.WriteString("}\n")
|
||||
b.WriteString("}\n")
|
||||
b.WriteString("}\n")
|
||||
b.WriteString("return false\n")
|
||||
return b.String()
|
||||
},
|
||||
})
|
||||
}
|
||||
f = append(f, &defs.FunctionDef{
|
||||
Name: "IsActivityType",
|
||||
Comment: "Returns true if the provided Typer is an Activity.",
|
||||
Args: []*defs.FunctionVarDef{{Name: "t", Type: "Typer"}},
|
||||
Return: []*defs.FunctionVarDef{{Name: "b", Type: "bool"}},
|
||||
Body: func() string {
|
||||
var b bytes.Buffer
|
||||
b.WriteString(fmt.Sprintf("var activityTypes = []string{\"%s\"}\n", strings.Join(activityTypes, "\", \"")))
|
||||
b.WriteString("hasType := make(map[string]bool, 1)\n")
|
||||
b.WriteString("for i := 0; i < t.TypeLen(); i++ {\n")
|
||||
b.WriteString("v := t.GetType(i)\n")
|
||||
b.WriteString("if s, ok := v.(string); ok {\n")
|
||||
b.WriteString("hasType[s] = true\n")
|
||||
b.WriteString("}\n")
|
||||
b.WriteString("}\n")
|
||||
b.WriteString("for _, t := range activityTypes {\n")
|
||||
b.WriteString("if hasType[t] {\n")
|
||||
b.WriteString("return true\n")
|
||||
b.WriteString("}\n")
|
||||
b.WriteString("}\n")
|
||||
b.WriteString("return false\n")
|
||||
return b.String()
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func generatePackageDefinition() *defs.PackageDef {
|
||||
return &defs.PackageDef{
|
||||
Name: "vocab",
|
||||
|
|
1629
vocab/vocab.go
1629
vocab/vocab.go
ファイル差分が大きすぎるため省略します
差分を読み込み
読み込み中…
新しいイシューから参照