- Document all exported types, functions, methods, and constants across 52 files - Add package-level doc comments to client, models, utils, and ynison packages - Document HTTP method and endpoint path for each API client method - Document model struct fields and DeJSON/DeList/ToJSON/ToMap methods - Fix duplicate package doc comment in internal/models/base.go Co-Authored-By: Claude Code <noreply@anthropic.com>
276 lines
7.4 KiB
Go
276 lines
7.4 KiB
Go
// Package models provides data models for the Yandex Music API.
|
|
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
)
|
|
|
|
// Album represents a full album from the Yandex Music API.
|
|
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 data.
|
|
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 from JSON data.
|
|
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 data.
|
|
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 from JSON data.
|
|
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 for an album.
|
|
type Availability struct {
|
|
AvailableForPremiumUsers bool `json:"available_for_premium_users"`
|
|
Territories []string `json:"territories"`
|
|
}
|
|
|
|
// Upsell represents upsell info for an album.
|
|
type Upsell struct {
|
|
Type string `json:"type"`
|
|
Description string `json:"description"`
|
|
}
|
|
|
|
// Best represents best tracks info for an album.
|
|
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 data.
|
|
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 from JSON data.
|
|
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
|
|
}
|