package goap import ( "maps" ) type PublicKey struct { Id string Owner string Pem string } type Attachment struct { Type string Value string Name string } type Media struct { Type string Url string MediaType *string Sensitive *bool } type IdValue struct { Id string } type ValueValue[T any] struct { Type *string Value T OtherThings map[string]any } func (p PublicKey) Marshal() map[string]any { return map[string]any{ KEY_ID: p.Id, KEY_W3_SECURITY_OWNER: IdValue{Id: p.Owner}.Marshal(), } } func (a Attachment) Marshal() map[string]any { return map[string]any{ KEY_TYPE: []string{KEY_SCHEMA_PROPERTYVALUE}, KEY_SCHEMA_VALUE: []map[string]any{ValueValue[string]{Value: a.Value}.Marshal()}, KEY_ACTIVITYSTREAMS_NAME: []map[string]any{ValueValue[string]{Value: a.Name}.Marshal()}, } } func (i IdValue) Marshal() map[string]any { return map[string]any{ KEY_ID: i.Id, } } func (v ValueValue[T]) Marshal() map[string]any { m := maps.Clone(v.OtherThings) if m == nil { m = map[string]any{} } m[KEY_VALUE] = v.Value if v.Type != nil { m[KEY_TYPE] = *v.Type } return m } func (m Media) Marshal() map[string]any { t := map[string]any{ KEY_TYPE: []string{m.Type}, KEY_ACTIVITYSTREAMS_URL: []map[string]any{IdValue{Id: m.Url}.Marshal()}, } if m.MediaType != nil { t[KEY_ACTIVITYSTREAMS_MEDIATYPE] = []map[string]any{{KEY_VALUE: *m.MediaType}} } if m.Sensitive != nil { t[KEY_ACTIVITYSTREAMS_SENSITIVE] = []map[string]any{{KEY_VALUE: *m.Sensitive}} } return t } func ParsePublicKey(_ map[string]any) (PublicKey, error) { return PublicKey{}, NotImplementedError{} } func ParseAttachment(raw map[string]any) (*Attachment, error) { attachment := Attachment{} rawType, ok := raw[KEY_VALUE] if !ok { return nil, NoRequiredFieldError{KEY_VALUE} } types, ok := rawType.([]string) if !ok { return nil, BadFieldValueError[[]string]{KEY_VALUE, rawType, []string{}} } if len(types) != 1 { return nil, BadFieldArrayLengthError{KEY_VALUE, 1, len(types)} } attachment.Type = types[0] rawValueWrapper, ok := raw[KEY_SCHEMA_VALUE] if !ok { return nil, NoRequiredFieldError{KEY_SCHEMA_VALUE} } valueWrapper, ok := rawValueWrapper.([]map[string]any) if !ok { return nil, BadFieldValueError[[]map[string]any]{ KEY_SCHEMA_VALUE, rawValueWrapper, []map[string]any{}, } } if len(valueWrapper) != 1 { return nil, BadFieldArrayLengthError{KEY_SCHEMA_VALUE, 1, len(types)} } rawValue, ok := valueWrapper[0][KEY_VALUE] if !ok { return nil, NoRequiredSubFieldError{KEY_SCHEMA_VALUE, KEY_VALUE} } value, ok := rawValue.(string) if !ok { return nil, BadFieldValueError[string]{KEY_VALUE, rawValue, ""} } attachment.Value = value rawNameWrapper, ok := raw[KEY_ACTIVITYSTREAMS_NAME] if !ok { return nil, NoRequiredFieldError{KEY_ACTIVITYSTREAMS_NAME} } nameWrapper, ok := rawNameWrapper.([]map[string]any) if !ok { return nil, BadFieldValueError[[]map[string]any]{ KEY_ACTIVITYSTREAMS_NAME, rawNameWrapper, []map[string]any{}, } } if len(nameWrapper) != 1 { return nil, BadFieldArrayLengthError{KEY_ACTIVITYSTREAMS_NAME, 1, len(nameWrapper)} } rawName, ok := valueWrapper[0][KEY_VALUE] if !ok { return nil, NoRequiredSubFieldError{KEY_ACTIVITYSTREAMS_NAME, KEY_VALUE} } name, ok := rawName.(string) if !ok { return nil, BadFieldValueError[string]{KEY_VALUE, rawValue, ""} } attachment.Name = name return &attachment, nil } func ParseMedia(raw map[string]any) (*Media, error) { rawType, ok := raw[KEY_TYPE] if !ok { return nil, NoRequiredFieldError{KEY_TYPE} } typeValues, ok := rawType.([]string) if !ok { return nil, BadFieldValueError[[]string]{KEY_TYPE, rawType, typeValues} } if len(typeValues) != 1 { return nil, BadFieldArrayLengthError{KEY_TYPE, 1, len(typeValues)} } typeValue := typeValues[0] urlId, err := ParseIdTypeWithName(raw, nil, KEY_ACTIVITYSTREAMS_URL) if err != nil { return nil, err } media := Media{ Type: typeValue, Url: urlId.Id, } if rawSensitiveData1, ok := raw[KEY_ACTIVITYSTREAMS_SENSITIVE]; ok { if sensitiveData1, ok := rawSensitiveData1.([]map[string]any); ok && len(sensitiveData1) == 1 { if v, err := ParseValueValue[bool](sensitiveData1[0]); err == nil { media.Sensitive = &v.Value } } } if rawMediatypeData1, ok := raw[KEY_ACTIVITYSTREAMS_MEDIATYPE]; ok { if mediatypeData1, ok := rawMediatypeData1.([]map[string]any); ok && len(mediatypeData1) == 1 { if v, err := ParseValueValue[string](mediatypeData1[0]); err == nil { media.MediaType = &v.Value } } } return &media, nil } func ParseIdValue(r map[string]any) (*IdValue, error) { rawId, ok := r[KEY_ID] if !ok { return nil, NoRequiredFieldError{KEY_ID} } id, ok := rawId.(string) if !ok { return nil, BadFieldValueError[string]{KEY_ID, rawId, id} } return &IdValue{Id: id}, nil } func ParseValueValue[T any](raw map[string]any) (*ValueValue[T], error) { otherData := map[string]any{} var typeString *string = nil var rawValue any = nil valSet := false for k, v := range raw { switch k { case KEY_VALUE: valSet = true rawValue = v case KEY_TYPE: parsed, ok := v.(string) if !ok { return nil, BadFieldValueError[string]{KEY_TYPE, v, ""} } typeString = &parsed default: otherData[k] = v } } if !valSet { return nil, NoRequiredFieldError{KEY_VALUE} } val, ok := rawValue.(T) if !ok { return nil, BadFieldValueError[T]{KEY_VALUE, rawValue, val} } return &ValueValue[T]{ Value: val, Type: typeString, OtherThings: otherData, }, nil }