diff --git a/metadata/extra.go b/metadata/extra.go index 8389a29..0d5fec5 100644 --- a/metadata/extra.go +++ b/metadata/extra.go @@ -1,40 +1,61 @@ package metadata import ( + "encoding/json" + "errors" "git.lumeweb.com/LumeWeb/libs5-go/encoding" "git.lumeweb.com/LumeWeb/libs5-go/types" "github.com/vmihailenco/msgpack/v5" ) +var names = map[types.MetadataExtension]string{ + types.MetadataExtensionLicenses: "licenses", + types.MetadataExtensionDonationKeys: "donationKeys", + types.MetadataExtensionWikidataClaims: "wikidataClaims", + types.MetadataExtensionLanguages: "languages", + types.MetadataExtensionSourceUris: "sourceUris", + types.MetadataExtensionPreviousVersions: "previousVersions", + types.MetadataExtensionTimestamp: "timestamp", + types.MetadataExtensionOriginalTimestamp: "originalTimestamp", + types.MetadataExtensionTags: "tags", + types.MetadataExtensionCategories: "categories", + types.MetadataExtensionBasicMediaMetadata: "basicMediaMetadata", + types.MetadataExtensionViewTypes: "viewTypes", + types.MetadataExtensionBridge: "bridge", + types.MetadataExtensionRoutingHints: "routingHints", +} + +var namesReverse = map[string]types.MetadataExtension{ + "licenses": types.MetadataExtensionLicenses, + "donationKeys": types.MetadataExtensionDonationKeys, + "wikidataClaims": types.MetadataExtensionWikidataClaims, + "languages": types.MetadataExtensionLanguages, + "sourceUris": types.MetadataExtensionSourceUris, + "previousVersions": types.MetadataExtensionPreviousVersions, + "timestamp": types.MetadataExtensionTimestamp, + "originalTimestamp": types.MetadataExtensionOriginalTimestamp, + "tags": types.MetadataExtensionTags, + "categories": types.MetadataExtensionCategories, + "basicMediaMetadata": types.MetadataExtensionBasicMediaMetadata, + "viewTypes": types.MetadataExtensionViewTypes, + "bridge": types.MetadataExtensionBridge, + "routingHints": types.MetadataExtensionRoutingHints, +} + type ExtraMetadata struct { Data map[int]interface{} } +var _ SerializableMetadata = (*ExtraMetadata)(nil) + func NewExtraMetadata(data map[int]interface{}) *ExtraMetadata { return &ExtraMetadata{ Data: data, } } -func (em *ExtraMetadata) ToJSON() map[string]interface{} { +func (em ExtraMetadata) MarshalJSON() ([]byte, error) { jsonObject := make(map[string]interface{}) - names := map[types.MetadataExtension]string{ - types.MetadataExtensionLicenses: "licenses", - types.MetadataExtensionDonationKeys: "donationKeys", - types.MetadataExtensionWikidataClaims: "wikidataClaims", - types.MetadataExtensionLanguages: "languages", - types.MetadataExtensionSourceUris: "sourceUris", - types.MetadataExtensionPreviousVersions: "previousVersions", - types.MetadataExtensionTimestamp: "timestamp", - types.MetadataExtensionOriginalTimestamp: "originalTimestamp", - types.MetadataExtensionTags: "tags", - types.MetadataExtensionCategories: "categories", - types.MetadataExtensionBasicMediaMetadata: "basicMediaMetadata", - types.MetadataExtensionViewTypes: "viewTypes", - types.MetadataExtensionBridge: "bridge", - types.MetadataExtensionRoutingHints: "routingHints", - } - for key, value := range em.Data { name, ok := names[types.MetadataExtension(key)] if ok { @@ -50,15 +71,43 @@ func (em *ExtraMetadata) ToJSON() map[string]interface{} { } else { jsonObject["updateCID"] = "" } - } else { jsonObject[name] = value } } } - return jsonObject + return json.Marshal(jsonObject) } + +func (em *ExtraMetadata) UnmarshalJSON(data []byte) error { + // Intermediate representation of the expected JSON structure + jsonObject := make(map[string]interface{}) + if err := json.Unmarshal(data, &jsonObject); err != nil { + return err + } + + em.Data = make(map[int]interface{}) + for name, value := range jsonObject { + if key, ok := namesReverse[name]; ok { + if key == types.MetadataExtensionUpdateCID { + // Convert string back to CID bytes + cid, err := encoding.Decode(value.(string)) + if err != nil { + return err + } + em.Data[int(key)] = cid + } else { + em.Data[int(key)] = value + } + } else { + return errors.New("unknown key in JSON: " + name) + } + } + + return nil +} + func (em *ExtraMetadata) DecodeMsgpack(dec *msgpack.Decoder) error { mapLen, err := dec.DecodeMapLen()