You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
2.4 KiB
115 lines
2.4 KiB
package models
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
)
|
|
|
|
// A Tag associates a story with other content, like other stories, logs and more.
|
|
type Tag struct {
|
|
Kind TagKind `bson:"kind"`
|
|
Name string `bson:"name"`
|
|
}
|
|
|
|
func (tag *Tag) Decode(v string) error {
|
|
split := strings.SplitN(v, ":", 2)
|
|
if len(split) == 1 {
|
|
return errors.New("bad tag name: " + v)
|
|
}
|
|
|
|
kind := TagKind("")
|
|
err := kind.UnmarshalGQL(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tag.Kind = kind
|
|
tag.Name = split[1]
|
|
|
|
return nil
|
|
}
|
|
|
|
func (tag *Tag) String() string {
|
|
return string(tag.Kind) + ":" + tag.Name
|
|
}
|
|
|
|
// Equal returns true if the tags match one another.
|
|
func (tag *Tag) Equal(other Tag) bool {
|
|
return tag.Kind == other.Kind && tag.Name == other.Name
|
|
}
|
|
|
|
// IsChangeObject is an interface implementation to identify it as a valid
|
|
// ChangeObject in GQL.
|
|
func (*Tag) IsChangeObject() {
|
|
panic("this method is a dummy, and so is its caller")
|
|
}
|
|
|
|
func EncodeTagArray(arr []Tag) []string {
|
|
result := make([]string, len(arr))
|
|
for i, v := range arr {
|
|
result[i] = v.String()
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func DecodeTagArray(arr []string) ([]*Tag, error) {
|
|
result := make([]*Tag, 0, len(arr))
|
|
for i, v := range arr {
|
|
result = append(result, &Tag{})
|
|
err := result[i].Decode(v)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// TagKind represents the kind of tags.
|
|
type TagKind string
|
|
|
|
const (
|
|
// TagKindOrganization is a tag kind, see GraphQL documentation.
|
|
TagKindOrganization TagKind = "Organization"
|
|
|
|
// TagKindCharacter is a tag kind, see GraphQL documentation.
|
|
TagKindCharacter TagKind = "Character"
|
|
|
|
// TagKindLocation is a tag kind, see GraphQL documentation.
|
|
TagKindLocation TagKind = "Location"
|
|
|
|
// TagKindEvent is a tag kind, see GraphQL documentation.
|
|
TagKindEvent TagKind = "Event"
|
|
|
|
// TagKindSeries is a tag kind, see GraphQL documentation.
|
|
TagKindSeries TagKind = "Series"
|
|
)
|
|
|
|
// UnmarshalGQL unmarshals
|
|
func (e *TagKind) UnmarshalGQL(v interface{}) error {
|
|
str, ok := v.(string)
|
|
if !ok {
|
|
return fmt.Errorf("enums must be strings")
|
|
}
|
|
|
|
*e = TagKind(str)
|
|
switch *e {
|
|
case TagKindOrganization, TagKindCharacter, TagKindLocation, TagKindEvent, TagKindSeries:
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("%s is not a valid TagKind", str)
|
|
}
|
|
}
|
|
|
|
// MarshalGQL turns it into a JSON string
|
|
func (e TagKind) MarshalGQL(w io.Writer) {
|
|
_, _ = fmt.Fprintf(w, "\"%s\"", string(e))
|
|
}
|
|
|
|
// TagFilter is a filter for tag listing.
|
|
type TagFilter struct {
|
|
Kind *TagKind `bson:"kind,omitempty"`
|
|
}
|