Files
MrixsandClaude Code 0456ca0665 Add comprehensive godoc documentation to all exported symbols
- 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>
2026-10-18 08:57:43 +03:00

409 lines
12 KiB
Go

// Package models provides data models for the Yandex Music API.
package models
import (
"encoding/json"
)
// Playlist represents a playlist from the Yandex Music API.
type Playlist struct {
BaseModel
Kind int `json:"kind"`
Title string `json:"title"`
Description string `json:"description"`
CoverURI string `json:"cover_uri"`
Created string `json:"created"`
Modified string `json:"modified"`
TrackCount int `json:"track_count"`
DurationMs int `json:"duration_ms"`
Availability *Availability `json:"availability"`
Owner *User `json:"owner"`
Tracks []Track `json:"tracks"`
LikesCount int `json:"likes_count"`
IsPublic bool `json:"is_public"`
Revision int `json:"revision"`
UUID string `json:"uuid"`
Tags []string `json:"tags"`
SimilarPlaylists []Playlist `json:"similar_playlists"`
// Additional fields
AccessType string `json:"access_type"`
Available bool `json:"available"`
ContentWarning string `json:"content_warning"`
Genre string `json:"genre"`
Image []Image `json:"image"`
OwnerUID int64 `json:"owner_uid"`
Shared bool `json:"shared"`
SnapshotID string `json:"snapshot_id"`
Trailer *TrailerInfo `json:"trailer"`
}
// DeJSON deserializes a Playlist from JSON data.
func (p *Playlist) DeJSON(data []byte, c ClientInterface) (Model, error) {
var raw map[string]json.RawMessage
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
playlist := &Playlist{BaseModel: *NewBaseModel(c)}
// Simple fields
if v, ok := raw["kind"]; ok {
json.Unmarshal(v, &playlist.Kind)
}
if v, ok := raw["title"]; ok {
json.Unmarshal(v, &playlist.Title)
}
if v, ok := raw["description"]; ok {
json.Unmarshal(v, &playlist.Description)
}
if v, ok := raw["cover_uri"]; ok {
json.Unmarshal(v, &playlist.CoverURI)
}
if v, ok := raw["created"]; ok {
json.Unmarshal(v, &playlist.Created)
}
if v, ok := raw["modified"]; ok {
json.Unmarshal(v, &playlist.Modified)
}
if v, ok := raw["track_count"]; ok {
json.Unmarshal(v, &playlist.TrackCount)
}
if v, ok := raw["duration_ms"]; ok {
json.Unmarshal(v, &playlist.DurationMs)
}
if v, ok := raw["likes_count"]; ok {
json.Unmarshal(v, &playlist.LikesCount)
}
if v, ok := raw["is_public"]; ok {
json.Unmarshal(v, &playlist.IsPublic)
}
if v, ok := raw["revision"]; ok {
json.Unmarshal(v, &playlist.Revision)
}
if v, ok := raw["uuid"]; ok {
json.Unmarshal(v, &playlist.UUID)
}
if v, ok := raw["tags"]; ok {
json.Unmarshal(v, &playlist.Tags)
}
if v, ok := raw["access_type"]; ok {
json.Unmarshal(v, &playlist.AccessType)
}
if v, ok := raw["available"]; ok {
json.Unmarshal(v, &playlist.Available)
}
if v, ok := raw["content_warning"]; ok {
json.Unmarshal(v, &playlist.ContentWarning)
}
if v, ok := raw["genre"]; ok {
json.Unmarshal(v, &playlist.Genre)
}
if v, ok := raw["owner_uid"]; ok {
json.Unmarshal(v, &playlist.OwnerUID)
}
if v, ok := raw["shared"]; ok {
json.Unmarshal(v, &playlist.Shared)
}
if v, ok := raw["snapshot_id"]; ok {
json.Unmarshal(v, &playlist.SnapshotID)
}
// Nested objects
if v, ok := raw["availability"]; ok {
var avail Availability
json.Unmarshal(v, &avail)
playlist.Availability = &avail
}
if v, ok := raw["owner"]; ok {
var user User
json.Unmarshal(v, &user)
playlist.Owner = &user
}
if v, ok := raw["tracks"]; ok {
var tracks []Track
json.Unmarshal(v, &tracks)
playlist.Tracks = tracks
}
if v, ok := raw["similar_playlists"]; ok {
var similar []Playlist
json.Unmarshal(v, &similar)
playlist.SimilarPlaylists = similar
}
if v, ok := raw["image"]; ok {
var images []Image
json.Unmarshal(v, &images)
playlist.Image = images
}
if v, ok := raw["trailer"]; ok {
var trailer TrailerInfo
json.Unmarshal(v, &trailer)
playlist.Trailer = &trailer
}
return playlist, nil
}
// DeList deserializes a list of Playlists from JSON data.
func (p *Playlist) 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 {
playlist := &Playlist{BaseModel: *NewBaseModel(c)}
if err := json.Unmarshal(item, playlist); err != nil {
continue
}
result = append(result, playlist)
}
return result, nil
}
// User represents a user (playlist owner) from the Yandex Music API.
type User struct {
BaseModel
UID int64 `json:"uid"`
Login string `json:"login"`
DisplayName string `json:"display_name"`
CoverURI string `json:"cover_uri"`
Sex string `json:"sex"`
PublicPlaylists int `json:"public_playlists"`
FollowersCount int `json:"followers_count"`
FollowingsCount int `json:"followings_count"`
HasPlaylists bool `json:"has_playlists"`
Available bool `json:"available"`
// Additional fields
Description string `json:"description"`
IsVerified bool `json:"is_verified"`
City string `json:"city"`
Country string `json:"country"`
Birthday string `json:"birthday"`
RegistrationDate string `json:"registration_date"`
Settings *UserSettings `json:"settings"`
Counters *UserCounters `json:"counters"`
}
// DeJSON deserializes a User from JSON data.
func (u *User) DeJSON(data []byte, c ClientInterface) (Model, error) {
var raw map[string]json.RawMessage
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
user := &User{BaseModel: *NewBaseModel(c)}
if v, ok := raw["uid"]; ok {
json.Unmarshal(v, &user.UID)
}
if v, ok := raw["login"]; ok {
json.Unmarshal(v, &user.Login)
}
if v, ok := raw["display_name"]; ok {
json.Unmarshal(v, &user.DisplayName)
}
if v, ok := raw["cover_uri"]; ok {
json.Unmarshal(v, &user.CoverURI)
}
if v, ok := raw["sex"]; ok {
json.Unmarshal(v, &user.Sex)
}
if v, ok := raw["public_playlists"]; ok {
json.Unmarshal(v, &user.PublicPlaylists)
}
if v, ok := raw["followers_count"]; ok {
json.Unmarshal(v, &user.FollowersCount)
}
if v, ok := raw["followings_count"]; ok {
json.Unmarshal(v, &user.FollowingsCount)
}
if v, ok := raw["has_playlists"]; ok {
json.Unmarshal(v, &user.HasPlaylists)
}
if v, ok := raw["available"]; ok {
json.Unmarshal(v, &user.Available)
}
if v, ok := raw["description"]; ok {
json.Unmarshal(v, &user.Description)
}
if v, ok := raw["is_verified"]; ok {
json.Unmarshal(v, &user.IsVerified)
}
if v, ok := raw["city"]; ok {
json.Unmarshal(v, &user.City)
}
if v, ok := raw["country"]; ok {
json.Unmarshal(v, &user.Country)
}
if v, ok := raw["birthday"]; ok {
json.Unmarshal(v, &user.Birthday)
}
if v, ok := raw["registration_date"]; ok {
json.Unmarshal(v, &user.RegistrationDate)
}
if v, ok := raw["settings"]; ok {
var settings UserSettings
json.Unmarshal(v, &settings)
user.Settings = &settings
}
if v, ok := raw["counters"]; ok {
var counters UserCounters
json.Unmarshal(v, &counters)
user.Counters = &counters
}
return user, nil
}
// DeList deserializes a list of Users from JSON data.
func (u *User) 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 {
user := &User{BaseModel: *NewBaseModel(c)}
if err := json.Unmarshal(item, user); err != nil {
continue
}
result = append(result, user)
}
return result, nil
}
// UserSettings represents user settings from /account/settings.
type UserSettings struct {
BaseModel
UID int64 `json:"uid"`
LastFMScrobblingEnabled bool `json:"last_fm_scrobbling_enabled"`
ShuffleEnabled bool `json:"shuffle_enabled"`
VolumePercents int `json:"volume_percents"`
Modified string `json:"modified"`
FacebookScrobblingEnabled bool `json:"facebook_scrobbling_enabled"`
AddNewTrackOnPlaylistTop bool `json:"add_new_track_on_playlist_top"`
UserMusicVisibility string `json:"user_music_visibility"`
UserSocialVisibility string `json:"user_social_visibility"`
RBTDisabled bool `json:"rbt_disabled"`
Theme string `json:"theme"`
PromosDisabled bool `json:"promos_disabled"`
AutoPlayRadio bool `json:"auto_play_radio"`
SyncQueueEnabled bool `json:"sync_queue_enabled"`
AdsDisabled *bool `json:"ads_disabled,omitempty"`
DiskEnabled *bool `json:"disk_enabled,omitempty"`
ShowDiskTracksInLibrary *bool `json:"show_disk_tracks_in_library,omitempty"`
}
// DeJSON deserializes UserSettings from JSON data.
func (u *UserSettings) DeJSON(data []byte, c ClientInterface) (Model, error) {
var raw map[string]json.RawMessage
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
settings := &UserSettings{BaseModel: *NewBaseModel(c)}
if v, ok := raw["uid"]; ok {
json.Unmarshal(v, &settings.UID)
}
if v, ok := raw["last_fm_scrobbling_enabled"]; ok {
json.Unmarshal(v, &settings.LastFMScrobblingEnabled)
}
if v, ok := raw["shuffle_enabled"]; ok {
json.Unmarshal(v, &settings.ShuffleEnabled)
}
if v, ok := raw["volume_percents"]; ok {
json.Unmarshal(v, &settings.VolumePercents)
}
if v, ok := raw["modified"]; ok {
json.Unmarshal(v, &settings.Modified)
}
if v, ok := raw["facebook_scrobbling_enabled"]; ok {
json.Unmarshal(v, &settings.FacebookScrobblingEnabled)
}
if v, ok := raw["add_new_track_on_playlist_top"]; ok {
json.Unmarshal(v, &settings.AddNewTrackOnPlaylistTop)
}
if v, ok := raw["user_music_visibility"]; ok {
json.Unmarshal(v, &settings.UserMusicVisibility)
}
if v, ok := raw["user_social_visibility"]; ok {
json.Unmarshal(v, &settings.UserSocialVisibility)
}
if v, ok := raw["rbt_disabled"]; ok {
json.Unmarshal(v, &settings.RBTDisabled)
}
if v, ok := raw["theme"]; ok {
json.Unmarshal(v, &settings.Theme)
}
if v, ok := raw["promos_disabled"]; ok {
json.Unmarshal(v, &settings.PromosDisabled)
}
if v, ok := raw["auto_play_radio"]; ok {
json.Unmarshal(v, &settings.AutoPlayRadio)
}
if v, ok := raw["sync_queue_enabled"]; ok {
json.Unmarshal(v, &settings.SyncQueueEnabled)
}
if v, ok := raw["ads_disabled"]; ok {
var val bool
json.Unmarshal(v, &val)
settings.AdsDisabled = &val
}
if v, ok := raw["disk_enabled"]; ok {
var val bool
json.Unmarshal(v, &val)
settings.DiskEnabled = &val
}
if v, ok := raw["show_disk_tracks_in_library"]; ok {
var val bool
json.Unmarshal(v, &val)
settings.ShowDiskTracksInLibrary = &val
}
return settings, nil
}
// DeList deserializes a list of UserSettings from JSON data.
func (u *UserSettings) 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 {
settings := &UserSettings{BaseModel: *NewBaseModel(c)}
if err := json.Unmarshal(item, settings); err != nil {
continue
}
result = append(result, settings)
}
return result, nil
}
// UserCounters represents user counters.
type UserCounters struct {
Tracks int `json:"tracks"`
Albums int `json:"albums"`
Playlists int `json:"playlists"`
Followers int `json:"followers"`
Followings int `json:"followings"`
Likes int `json:"likes"`
}
// Image represents an image with multiple sizes.
type Image struct {
URI string `json:"uri"`
Type string `json:"type"`
Width int `json:"width"`
Height int `json:"height"`
Size int64 `json:"size"`
Extension string `json:"extension"`
}
// Re-export types from other files for convenience
// Availability, TrailerInfo are defined in album.go