diff --git a/internal/radio/playlist.go b/internal/radio/playlist.go new file mode 100644 index 0000000..65bd67a --- /dev/null +++ b/internal/radio/playlist.go @@ -0,0 +1,56 @@ +package radio + +import ( + "os" + "strings" + "sync" +) + +// Playlist holds a list of paths to a song files. +type Playlist struct { + mut sync.Mutex + filePath string + playlist []string + cur int + repeat bool +} + +// NewPlaylist returns an instance of a Playlist struct with a loaded playlist. +// Returns an error if failed to load a playlist file. +func NewPlaylist(filePath string, repeat bool) (*Playlist, error) { + p := &Playlist{filePath: filePath, repeat: repeat} + return p, p.Load() +} + +// Next returns the next song to play. Returns an empty string if repeat is +// false and the end of a playlist was reached. +func (p *Playlist) Next() (song string) { + p.mut.Lock() + defer p.mut.Unlock() + if p.cur == len(p.playlist) { + // If the end of a playlist was reached and repeat is set to true, + // then go back to the head of it, thus repeating it. Return an empty + // string otherwise. + if p.repeat { + p.cur = 0 + } else { + return "" + } + } + song = p.playlist[p.cur] + p.cur++ + return +} + +// Load reads a playlist file and fills. +func (p *Playlist) Load() error { + data, err := os.ReadFile(p.filePath) + if err != nil { + return err + } + p.mut.Lock() + p.playlist = strings.Split(string(data), "\n") + p.cur = 0 + p.mut.Unlock() + return nil +}