package models import ( "encoding/json" ) // Album represents a full album type Album struct { BaseModel ID string `json:"id"` Title string `json:"title"` CoverURI string `json:"cover_uri"` Genre string `json:"genre"` Year int `json:"year"` TrackCount int `json:"track_count"` Available bool `json:"available"` ReleaseDate string `json:"release_date"` Artists []Artist `json:"artists"` Labels []Label `json:"labels"` Volumes [][]Track `json:"volumes"` Description string `json:"description"` Meta *AlbumMeta `json:"meta"` Best *Best `json:"best"` // Additional fields Region string `json:"region"` AvailableForPremiumUsers bool `json:"available_for_premium_users"` AvailableForPremiumUsersOnly bool `json:"available_for_premium_users_only"` ContentWarning string `json:"content_warning"` Label string `json:"label"` CatalogNumber string `json:"catalog_number"` Options []string `json:"options"` TrackPositions []TrackPosition `json:"track_positions"` SimilarAlbums []Album `json:"similar_albums"` Trailer *TrailerInfo `json:"trailer"` } // DeJSON deserializes an Album from JSON func (a *Album) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { return nil, err } album := &Album{BaseModel: *NewBaseModel(c)} // Simple fields if v, ok := raw["id"]; ok { json.Unmarshal(v, &album.ID) } if v, ok := raw["title"]; ok { json.Unmarshal(v, &album.Title) } if v, ok := raw["cover_uri"]; ok { json.Unmarshal(v, &album.CoverURI) } if v, ok := raw["genre"]; ok { json.Unmarshal(v, &album.Genre) } if v, ok := raw["year"]; ok { json.Unmarshal(v, &album.Year) } if v, ok := raw["track_count"]; ok { json.Unmarshal(v, &album.TrackCount) } if v, ok := raw["available"]; ok { json.Unmarshal(v, &album.Available) } if v, ok := raw["release_date"]; ok { json.Unmarshal(v, &album.ReleaseDate) } if v, ok := raw["description"]; ok { json.Unmarshal(v, &album.Description) } if v, ok := raw["region"]; ok { json.Unmarshal(v, &album.Region) } if v, ok := raw["available_for_premium_users"]; ok { json.Unmarshal(v, &album.AvailableForPremiumUsers) } if v, ok := raw["available_for_premium_users_only"]; ok { json.Unmarshal(v, &album.AvailableForPremiumUsersOnly) } if v, ok := raw["content_warning"]; ok { json.Unmarshal(v, &album.ContentWarning) } if v, ok := raw["label"]; ok { json.Unmarshal(v, &album.Label) } if v, ok := raw["catalog_number"]; ok { json.Unmarshal(v, &album.CatalogNumber) } if v, ok := raw["options"]; ok { json.Unmarshal(v, &album.Options) } // Nested objects if v, ok := raw["artists"]; ok { var artists []Artist json.Unmarshal(v, &artists) album.Artists = artists } if v, ok := raw["labels"]; ok { var labels []Label json.Unmarshal(v, &labels) album.Labels = labels } if v, ok := raw["volumes"]; ok { var volumes [][]Track json.Unmarshal(v, &volumes) album.Volumes = volumes } if v, ok := raw["meta"]; ok { var meta AlbumMeta json.Unmarshal(v, &meta) album.Meta = &meta } if v, ok := raw["best"]; ok { var best Best json.Unmarshal(v, &best) album.Best = &best } if v, ok := raw["track_positions"]; ok { var positions []TrackPosition json.Unmarshal(v, &positions) album.TrackPositions = positions } if v, ok := raw["similar_albums"]; ok { var similar []Album json.Unmarshal(v, &similar) album.SimilarAlbums = similar } if v, ok := raw["trailer"]; ok { var trailer TrailerInfo json.Unmarshal(v, &trailer) album.Trailer = &trailer } return album, nil } // DeList deserializes a list of Albums func (a *Album) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { return nil, err } result := make([]Model, 0, len(rawList)) for _, item := range rawList { album := &Album{BaseModel: *NewBaseModel(c)} if err := json.Unmarshal(item, album); err != nil { continue } result = append(result, album) } return result, nil } // AlbumMeta represents album metadata type AlbumMeta struct { BaseModel Availability *Availability `json:"availability"` Upsell *Upsell `json:"upsell"` } // DeJSON deserializes an AlbumMeta from JSON func (am *AlbumMeta) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { return nil, err } meta := &AlbumMeta{BaseModel: *NewBaseModel(c)} if v, ok := raw["availability"]; ok { var avail Availability json.Unmarshal(v, &avail) meta.Availability = &avail } if v, ok := raw["upsell"]; ok { var upsell Upsell json.Unmarshal(v, &upsell) meta.Upsell = &upsell } return meta, nil } // DeList deserializes a list of AlbumMeta func (am *AlbumMeta) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { return nil, err } result := make([]Model, 0, len(rawList)) for _, item := range rawList { meta := &AlbumMeta{BaseModel: *NewBaseModel(c)} if err := json.Unmarshal(item, meta); err != nil { continue } result = append(result, meta) } return result, nil } // Availability represents availability info type Availability struct { AvailableForPremiumUsers bool `json:"available_for_premium_users"` Territories []string `json:"territories"` } // Upsell represents upsell info type Upsell struct { Type string `json:"type"` Description string `json:"description"` } // Best represents best tracks info type Best struct { Tracks []Track `json:"tracks"` } // TrailerInfo represents album/track trailer info type TrailerInfo struct { BaseModel PreviewURI string `json:"preview_uri"` TrackID string `json:"track_id"` AlbumID string `json:"album_id"` Duration int `json:"duration"` } // DeJSON deserializes a TrailerInfo from JSON func (ti *TrailerInfo) DeJSON(data []byte, c ClientInterface) (Model, error) { var raw map[string]json.RawMessage if err := json.Unmarshal(data, &raw); err != nil { return nil, err } trailer := &TrailerInfo{BaseModel: *NewBaseModel(c)} if v, ok := raw["preview_uri"]; ok { json.Unmarshal(v, &trailer.PreviewURI) } if v, ok := raw["track_id"]; ok { json.Unmarshal(v, &trailer.TrackID) } if v, ok := raw["album_id"]; ok { json.Unmarshal(v, &trailer.AlbumID) } if v, ok := raw["duration"]; ok { json.Unmarshal(v, &trailer.Duration) } return trailer, nil } // DeList deserializes a list of TrailerInfo func (ti *TrailerInfo) DeList(data []byte, c ClientInterface) ([]Model, error) { var rawList []json.RawMessage if err := json.Unmarshal(data, &rawList); err != nil { return nil, err } result := make([]Model, 0, len(rawList)) for _, item := range rawList { trailer := &TrailerInfo{BaseModel: *NewBaseModel(c)} if err := json.Unmarshal(item, trailer); err != nil { continue } result = append(result, trailer) } return result, nil }