Files
go-mxl-player/internal/playback/playlist_navigation.go
T
2026-09-01 19:41:52 +03:00

94 lines
2.3 KiB
Go

package playback
import "errors"
type PlaylistCommandKind uint8
const (
PlaylistSelect PlaylistCommandKind = iota + 1
PlaylistNext
PlaylistPrevious
)
type PlaylistCommand struct {
Kind PlaylistCommandKind
Index int
}
type PlaylistState struct {
CurrentIndex int
HasSelection bool
}
var (
ErrPlaylistEmpty = errors.New("playlist is empty")
ErrPlaylistIndexOutOfRange = errors.New("playlist index is out of range")
ErrUnknownPlaylistCommand = errors.New("unknown playlist command")
)
func ApplyPlaylistCommand(
playlist Playlist,
current PlaylistState,
command PlaylistCommand,
) (PlaylistState, error) {
if err := playlist.Validate(); err != nil {
return current, err
}
if len(playlist.Entries) == 0 {
return current, ErrPlaylistEmpty
}
lastIndex := len(playlist.Entries) - 1
switch command.Kind {
case PlaylistSelect:
if command.Index < 0 || command.Index > lastIndex {
return current, ErrPlaylistIndexOutOfRange
}
return PlaylistState{CurrentIndex: command.Index, HasSelection: true}, nil
case PlaylistNext:
if !current.HasSelection {
return PlaylistState{CurrentIndex: 0, HasSelection: true}, nil
}
if current.CurrentIndex < 0 || current.CurrentIndex > lastIndex {
return current, ErrPlaylistIndexOutOfRange
}
if current.CurrentIndex == lastIndex {
if playlist.Loop {
return PlaylistState{CurrentIndex: 0, HasSelection: true}, nil
}
return current, nil
}
return PlaylistState{CurrentIndex: current.CurrentIndex + 1, HasSelection: true}, nil
case PlaylistPrevious:
if !current.HasSelection {
index := 0
if playlist.Loop {
index = lastIndex
}
return PlaylistState{CurrentIndex: index, HasSelection: true}, nil
}
if current.CurrentIndex < 0 || current.CurrentIndex > lastIndex {
return current, ErrPlaylistIndexOutOfRange
}
if current.CurrentIndex == 0 {
if playlist.Loop {
return PlaylistState{CurrentIndex: lastIndex, HasSelection: true}, nil
}
return current, nil
}
return PlaylistState{CurrentIndex: current.CurrentIndex - 1, HasSelection: true}, nil
default:
return current, ErrUnknownPlaylistCommand
}
}
func (s PlaylistState) Entry(playlist Playlist) (PlaylistEntry, bool) {
if !s.HasSelection || s.CurrentIndex < 0 || s.CurrentIndex >= len(playlist.Entries) {
return PlaylistEntry{}, false
}
return playlist.Entries[s.CurrentIndex], true
}