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 {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
if !isActivityType(typer) {
|
if !vocab.IsActivityType(typer) {
|
||||||
actorIri, err := f.SocialAPI.ActorIRI(c, r)
|
actorIri, err := f.SocialAPI.ActorIRI(c, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
|
|
|
@ -125,7 +125,7 @@ func serveActivityPubObject(c context.Context, a Application, clock Clock, w htt
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addResponseHeaders(w.Header(), clock, b)
|
addResponseHeaders(w.Header(), clock, b)
|
||||||
if hasType(pObj, tombstone) {
|
if vocab.HasTypeTombstone(pObj) {
|
||||||
w.WriteHeader(http.StatusGone)
|
w.WriteHeader(http.StatusGone)
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
|
@ -307,8 +307,7 @@ type PubObject interface {
|
||||||
|
|
||||||
// Typer is an object that has a type.
|
// Typer is an object that has a type.
|
||||||
type Typer interface {
|
type Typer interface {
|
||||||
TypeLen() (l int)
|
vocab.Typer
|
||||||
GetType(index int) (v interface{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// typeIder is a Typer with additional generic capabilities.
|
// 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) {
|
func (f *federator) addNewIds(c context.Context, a vocab.ActivityType) {
|
||||||
newId := f.App.NewId(c, a)
|
newId := f.App.NewId(c, a)
|
||||||
a.SetId(newId)
|
a.SetId(newId)
|
||||||
if hasType(a, create) {
|
if vocab.HasTypeCreate(a) {
|
||||||
for i := 0; i < a.ObjectLen(); i++ {
|
for i := 0; i < a.ObjectLen(); i++ {
|
||||||
if a.IsObject(i) {
|
if a.IsObject(i) {
|
||||||
obj := a.GetObject(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 {
|
func IRIFuncs() []*FunctionDef {
|
||||||
return []*FunctionDef{IriValueType.DeserializeFn, IriValueType.SerializeFn}
|
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"
|
"fmt"
|
||||||
"github.com/go-fed/activity/tools/defs"
|
"github.com/go-fed/activity/tools/defs"
|
||||||
"go/format"
|
"go/format"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
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, v.DeserializeFn, v.SerializeFn)
|
||||||
}
|
}
|
||||||
p.F = append(p.F, defs.IRIFuncs()...)
|
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
|
// Add functions to resolve string 'name' into concrete types
|
||||||
p.F = append(p.F, generateResolveObjectFunction(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()))
|
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 {
|
func generatePackageDefinition() *defs.PackageDef {
|
||||||
return &defs.PackageDef{
|
return &defs.PackageDef{
|
||||||
Name: "vocab",
|
Name: "vocab",
|
||||||
|
|
1629
vocab/vocab.go
1629
vocab/vocab.go
ファイル差分が大きすぎるため省略します
差分を読み込み
読み込み中…
新しいイシューから参照