gophertype/pkg/search/search.go

73 lines
1.2 KiB
Go

package search
import "strings"
// Search represents a parsed search query with inclusions and exclusions.
type Search struct {
Includes []string
Excludes []string
}
// ParseSearchString parses a user search query and supports "quoted phrases" and -negations.
func ParseSearchString(input string) *Search {
var result = new(Search)
var (
negate bool
phrase bool
buf = []rune{}
commit = func() {
var text = strings.TrimSpace(string(buf))
if len(text) == 0 {
return
}
if negate {
result.Excludes = append(result.Excludes, text)
negate = false
} else {
result.Includes = append(result.Includes, text)
}
buf = []rune{}
}
)
for _, char := range input {
// Inside a quoted phrase?
if phrase {
if char == '"' {
// End of quoted phrase.
commit()
phrase = false
continue
}
buf = append(buf, char)
continue
}
// Start a quoted phrase?
if char == '"' {
phrase = true
continue
}
// Negation indicator?
if len(buf) == 0 && char == '-' {
negate = true
continue
}
// End of a word?
if char == ' ' {
commit()
continue
}
buf = append(buf, char)
}
// Last word?
commit()
return result
}