biggest part of query parser

This commit is contained in:
Hazel Noack 2025-10-07 17:36:15 +02:00
parent acce599f2d
commit 59d3a4a953
3 changed files with 132 additions and 10 deletions

View File

@ -1,6 +1,9 @@
package common
import "strings"
import (
"errors"
"strings"
)
func Unify(s string) string {
s = strings.TrimSpace(s)
@ -10,3 +13,99 @@ func Unify(s string) string {
}
return s
}
type Query struct {
Search string
Artist string
Album string
Song string
}
const emptyChar = ' '
const songChar = 's'
const albumChar = 'r'
const artistChar = 'a'
func NewQuery(search string) (Query, error) {
search = strings.TrimSpace(search)
query := Query{
Search: search,
}
if search == "" {
return query, errors.New("search should not be empty")
}
parsed := make(map[rune]string)
indexChar := emptyChar
nextIsIndex := false
ignoreNextIfSpace := false
for _, char := range search {
// figuring out when the next char is an index char
if char == '#' {
// escape # => asserts previous char was also #
if nextIsIndex {
nextIsIndex = false
parsed[indexChar] = parsed[indexChar] + "#"
continue
}
nextIsIndex = true
continue
}
// setting an index char
if nextIsIndex {
if char != songChar && char != albumChar && char != artistChar {
return query, errors.New("the char after # has to be " + string(songChar) + ", " + string(albumChar) + " or " + string(artistChar) + " if it isn't escaped with another #")
}
if _, ok := parsed[char]; ok {
return query, errors.New("you can use #" + string(char) + " only once")
}
indexChar = char
nextIsIndex = false
ignoreNextIfSpace = true
parsed[char] = ""
continue
}
if ignoreNextIfSpace {
ignoreNextIfSpace = false
if char == ' ' {
continue
}
}
parsed[indexChar] = parsed[indexChar] + string(char)
}
if nextIsIndex {
return query, errors.New("there cant be an unescaped # at the end, it has to be escaped with another #")
}
if _, ok := parsed[emptyChar]; ok {
// no other index char should be used
e := errors.New("if you use advanced search with # you cant put anything before the first #")
if _, ok := parsed[songChar]; ok {
return query, e
}
if _, ok := parsed[albumChar]; ok {
return query, e
}
if _, ok := parsed[artistChar]; ok {
return query, e
}
query.Search = parsed[emptyChar]
} else {
query.Song = strings.TrimSpace(parsed[songChar])
query.Album = strings.TrimSpace(parsed[albumChar])
query.Artist = strings.TrimSpace(parsed[artistChar])
}
return query, nil
}

View File

@ -140,3 +140,7 @@ func Fetch(source data.Source) (data.MusicObject, error) {
return nil, nil
}
func Search(q string) {
}

37
main.go
View File

@ -1,20 +1,39 @@
package main
import (
"bufio"
"fmt"
"log"
"os"
"gitea.elara.ws/Hazel/music-kraken/internal/data"
"gitea.elara.ws/Hazel/music-kraken/internal/plugin"
"gitea.elara.ws/Hazel/music-kraken/internal/common"
)
func testQuery() {
for {
fmt.Print("> ")
reader := bufio.NewReader(os.Stdin)
line, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
return
}
query, err := common.NewQuery(line)
if err != nil {
fmt.Println(err)
}
fmt.Println("search: '" + query.Search + "'")
fmt.Println("artist: '" + query.Artist + "'")
fmt.Println("album: '" + query.Album + "'")
fmt.Println("song: '" + query.Song + "'")
fmt.Println()
}
}
func main() {
fmt.Println("music kraken")
plugin.RegisterPlugin(plugin.Musify{})
a, _ := plugin.Fetch(data.Source{
Url: "https://musify.club/artist/linkin-park-5",
})
artist := a.(data.Artist)
fmt.Println(artist.UnifiedName)
testQuery()
}