153 lines
3.8 KiB
Go
153 lines
3.8 KiB
Go
package goap
|
|
|
|
import "time"
|
|
|
|
type Tag interface {
|
|
Marshal() map[string]any
|
|
sealed()
|
|
}
|
|
|
|
type TagEmoji struct {
|
|
Id string
|
|
Icon Media
|
|
Name string
|
|
LastUpdated time.Time
|
|
}
|
|
|
|
func (t TagEmoji) sealed() {}
|
|
func (t TagEmoji) Marshal() map[string]any {
|
|
m := map[string]any{
|
|
KEY_ID: t.Id,
|
|
KEY_TYPE: []string{KEY_MASTO_EMOJI},
|
|
KEY_ACTIVITYSTREAMS_ICON: []map[string]any{t.Icon.Marshal()},
|
|
KEY_ACTIVITYSTREAMS_NAME: []map[string]any{{KEY_VALUE: t.Name}},
|
|
}
|
|
return m
|
|
}
|
|
|
|
type TagMention struct {
|
|
TargetId string
|
|
TargetName string
|
|
}
|
|
|
|
func (t TagMention) sealed() {}
|
|
func (t TagMention) Marshal() map[string]any {
|
|
return map[string]any{
|
|
KEY_TYPE: []string{KEY_ACTIVITYSTREAMS_MENTION},
|
|
KEY_ACTIVITYSTREAMS_HREF: []map[string]any{{KEY_ID: t.TargetId}},
|
|
KEY_ACTIVITYSTREAMS_NAME: []map[string]any{{KEY_VALUE: t.TargetName}},
|
|
}
|
|
}
|
|
|
|
type TagHashtag struct {
|
|
Url string
|
|
Name string
|
|
}
|
|
|
|
func (t TagHashtag) sealed() {}
|
|
func (t TagHashtag) Marshal() map[string]any {
|
|
return map[string]any{
|
|
KEY_TYPE: []string{KEY_ACTIVITYSTREAMS_HASHTAG},
|
|
KEY_ACTIVITYSTREAMS_HREF: []map[string]any{{KEY_ID: t.Url}},
|
|
KEY_ACTIVITYSTREAMS_NAME: []map[string]any{{KEY_VALUE: t.Name}},
|
|
}
|
|
}
|
|
|
|
func ParseTag(raw map[string]any) (Tag, error) {
|
|
rawTypeArr, ok := raw[KEY_TYPE]
|
|
if !ok {
|
|
return nil, NoRequiredFieldError{KEY_TYPE}
|
|
}
|
|
typeArr, ok := rawTypeArr.([]string)
|
|
if !ok {
|
|
return nil, BadFieldValueError[[]string]{KEY_TYPE, rawTypeArr, typeArr}
|
|
}
|
|
if len(typeArr) != 1 {
|
|
return nil, BadFieldArrayLengthError{KEY_TYPE, 1, len(typeArr)}
|
|
}
|
|
tagType := typeArr[0]
|
|
switch tagType {
|
|
case KEY_MASTO_EMOJI:
|
|
return parseEmojiTag(raw)
|
|
case KEY_ACTIVITYSTREAMS_MENTION:
|
|
return parseMentionTag(raw)
|
|
case KEY_ACTIVITYSTREAMS_HASHTAG:
|
|
return parseHashtagTag(raw)
|
|
default:
|
|
return nil, UnknownTagType{TagType: tagType}
|
|
}
|
|
}
|
|
|
|
func parseEmojiTag(raw map[string]any) (*TagEmoji, error) {
|
|
rawId, ok := raw[KEY_ID]
|
|
if !ok {
|
|
return nil, NoRequiredFieldError{KEY_ID}
|
|
}
|
|
id, ok := rawId.(string)
|
|
if !ok {
|
|
return nil, BadFieldValueError[string]{KEY_ID, rawId, id}
|
|
}
|
|
media, err := ParseASIconData(raw, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rawName1, ok := raw[KEY_ACTIVITYSTREAMS_NAME]
|
|
if !ok {
|
|
return nil, NoRequiredFieldError{KEY_ACTIVITYSTREAMS_NAME}
|
|
}
|
|
name1, ok := rawName1.([]map[string]any)
|
|
if !ok {
|
|
return nil, BadFieldValueError[[]map[string]any]{KEY_ACTIVITYSTREAMS_NAME, rawName1, name1}
|
|
}
|
|
if len(name1) != 1 {
|
|
return nil, BadFieldArrayLengthError{KEY_ACTIVITYSTREAMS_NAME, 1, len(name1)}
|
|
}
|
|
rawName2, ok := name1[0][KEY_VALUE]
|
|
if !ok {
|
|
return nil, NoRequiredSubFieldError{KEY_ACTIVITYSTREAMS_NAME, KEY_VALUE}
|
|
}
|
|
name2, ok := rawName2.(string)
|
|
if !ok {
|
|
return nil, BadFieldValueError[string]{KEY_VALUE, rawName2, name2}
|
|
}
|
|
|
|
// Casting media to ASIconData without check is ok here
|
|
// Reason: ParseASIconData returns an BaseAPChain, an interface.
|
|
// However, the function guarantees that, if it doesn't error out, you get an ASIconData struct back
|
|
return &TagEmoji{Id: id, Icon: media.(*ASIconData).Media, Name: name2}, nil
|
|
}
|
|
|
|
func parseMentionTag(raw map[string]any) (*TagMention, error) {
|
|
rawHref, err := ParseASHrefData(raw, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
href := rawHref.(*ASHrefData)
|
|
rawName, err := ParseASNameData(raw, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
name := rawName.(*ASNameData)
|
|
return &TagMention{
|
|
TargetId: href.Id,
|
|
TargetName: name.Value.Value,
|
|
}, nil
|
|
}
|
|
|
|
func parseHashtagTag(raw map[string]any) (*TagHashtag, error) {
|
|
rawHref, err := ParseASHrefData(raw, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
href := rawHref.(*ASHrefData)
|
|
rawName, err := ParseASNameData(raw, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
name := rawName.(*ASNameData)
|
|
return &TagHashtag{
|
|
Url: href.Id,
|
|
Name: name.Value.Value,
|
|
}, nil
|
|
}
|