package radio import ( "encoding/json" "sync" "time" ) type Song struct { mutex sync.Mutex Artist string Title string Duration time.Duration Listeners int64 MaxListeners int64 StartAt time.Time } func (s *Song) SetFrom(os *Song) { s.mutex.Lock() s.Artist = os.Artist s.Title = os.Title s.Duration = os.Duration s.Listeners = os.Listeners s.MaxListeners = os.MaxListeners s.StartAt = os.StartAt s.mutex.Unlock() } func (s *Song) UpdateMaxListeners(listeners int64) { s.mutex.Lock() if listeners > s.MaxListeners { s.MaxListeners = listeners } s.mutex.Unlock() } // IncListeners increments by one an overall amount of listeners of this song. func (s *Song) IncListeners() { s.mutex.Lock() s.Listeners++ s.mutex.Unlock() } // DurationString returns song's duration as a string formatted as [H:]M:SS. func (s *Song) DurationString() string { s.mutex.Lock() defer s.mutex.Unlock() if s.Duration.Hours() >= 1 { return time.UnixMilli(s.Duration.Milliseconds()).Format("3:4:05") } return time.UnixMilli(s.Duration.Milliseconds()).Format("4:05") } func (s *Song) MarshalJSON() ([]byte, error) { s.mutex.Lock() defer s.mutex.Unlock() return json.Marshal(&struct { Artist string `json:"artist"` Title string `json:"title"` DurationMill int64 `json:"duration_msec,omitempty"` Listeners int64 `json:"listeners"` MaxListeners int64 `json:"max_listeners"` StartAt string `json:"start_at"` }{ Artist: s.Artist, Title: s.Title, DurationMill: s.Duration.Milliseconds(), Listeners: s.Listeners, MaxListeners: s.MaxListeners, StartAt: s.StartAt.UTC().Format(time.RFC3339)}) }