Fix Album model to match Python reference
- Labels: changed from []Label to []LabelOrString (API returns both objects and strings) - Trailer: changed from *TrailerInfo to *AlbumTrailerStatus (Python has AlbumTrailerStatus with only 'available' field) - Added LabelOrString type with custom UnmarshalJSON - Added AlbumTrailerStatus type with Available field
This commit is contained in:
1 parent
6312c24b0f
commit
277a3e6924
2 files changed
+124
-58
No files matched your search
+106
-19
@@ -8,20 +8,20 @@ import (
|
||||
// Album represents a full album from the Yandex Music API.
|
||||
type Album struct {
|
||||
BaseModel
|
||||
ID JSONID `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"`
|
||||
ID JSONID `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 []LabelOrString `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"`
|
||||
@@ -32,7 +32,93 @@ type Album struct {
|
||||
Options []string `json:"options"`
|
||||
TrackPositions []TrackPosition `json:"track_positions"`
|
||||
SimilarAlbums []Album `json:"similar_albums"`
|
||||
Trailer *TrailerInfo `json:"trailer"`
|
||||
Trailer *AlbumTrailerStatus `json:"trailer"`
|
||||
}
|
||||
|
||||
// LabelOrString represents a label that can be either a Label object or a string.
|
||||
// The Yandex Music API sometimes returns labels as objects and sometimes as strings.
|
||||
type LabelOrString struct {
|
||||
Label *Label `json:"-"`
|
||||
Str string `json:"-"`
|
||||
IsStr bool `json:"-"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler, accepting both Label objects and strings.
|
||||
func (l *LabelOrString) UnmarshalJSON(data []byte) error {
|
||||
// Try string first
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err == nil {
|
||||
l.Str = s
|
||||
l.IsStr = true
|
||||
return nil
|
||||
}
|
||||
// Try Label object
|
||||
var label Label
|
||||
if err := json.Unmarshal(data, &label); err != nil {
|
||||
return err
|
||||
}
|
||||
l.Label = &label
|
||||
l.IsStr = false
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
func (l LabelOrString) MarshalJSON() ([]byte, error) {
|
||||
if l.IsStr {
|
||||
return json.Marshal(l.Str)
|
||||
}
|
||||
return json.Marshal(l.Label)
|
||||
}
|
||||
|
||||
// String returns the label as a string.
|
||||
func (l LabelOrString) String() string {
|
||||
if l.IsStr {
|
||||
return l.Str
|
||||
}
|
||||
if l.Label != nil {
|
||||
return l.Label.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// AlbumTrailerStatus represents trailer availability status for an album.
|
||||
type AlbumTrailerStatus struct {
|
||||
BaseModel
|
||||
Available bool `json:"available"`
|
||||
}
|
||||
|
||||
// DeJSON deserializes AlbumTrailerStatus from JSON data.
|
||||
func (ats *AlbumTrailerStatus) DeJSON(data []byte, c ClientInterface) (Model, error) {
|
||||
var raw map[string]json.RawMessage
|
||||
if err := json.Unmarshal(data, &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
status := &AlbumTrailerStatus{BaseModel: *NewBaseModel(c)}
|
||||
|
||||
if v, ok := raw["available"]; ok {
|
||||
json.Unmarshal(v, &status.Available)
|
||||
}
|
||||
|
||||
return status, nil
|
||||
}
|
||||
|
||||
// DeList deserializes a list of AlbumTrailerStatus from JSON data.
|
||||
func (ats *AlbumTrailerStatus) 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 {
|
||||
status := &AlbumTrailerStatus{BaseModel: *NewBaseModel(c)}
|
||||
if err := json.Unmarshal(item, status); err != nil {
|
||||
continue
|
||||
}
|
||||
result = append(result, status)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// DeJSON deserializes an Album from JSON data.
|
||||
@@ -101,9 +187,10 @@ func (a *Album) DeJSON(data []byte, c ClientInterface) (Model, error) {
|
||||
album.Artists = artists
|
||||
}
|
||||
if v, ok := raw["labels"]; ok {
|
||||
var labels []Label
|
||||
json.Unmarshal(v, &labels)
|
||||
album.Labels = labels
|
||||
var labels []LabelOrString
|
||||
if err := json.Unmarshal(v, &labels); err == nil {
|
||||
album.Labels = labels
|
||||
}
|
||||
}
|
||||
if v, ok := raw["volumes"]; ok {
|
||||
var volumes [][]Track
|
||||
@@ -131,7 +218,7 @@ func (a *Album) DeJSON(data []byte, c ClientInterface) (Model, error) {
|
||||
album.SimilarAlbums = similar
|
||||
}
|
||||
if v, ok := raw["trailer"]; ok {
|
||||
var trailer TrailerInfo
|
||||
var trailer AlbumTrailerStatus
|
||||
json.Unmarshal(v, &trailer)
|
||||
album.Trailer = &trailer
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user