package qualify import ( "strings" ) type Query map[string]Filter type Filter []string func (q Query) Query() string { if query, ok := q["query"]; ok { return strings.Join(query, " ") } return "" } func (f Filter) Last() string { return f[len(f)-1] } func Parse(text string, qualifiers ...string) Query { queries := make(map[string]Filter) for _, field := range fields(text) { var key, value string if k, v, ok := qualified(field, qualifiers...); ok { key = k value = trim(v) } else { key = "query" value = trim(field) } if queries[key] == nil { queries[key] = make([]string, 0) } queries[key] = append(queries[key], value) } return queries } func qualified(text string, qualifiers ...string) (string, string, bool) { if len(qualifiers) == 0 && strings.Contains(text, ":") { kv := strings.SplitN(text, ":", 2) return kv[0], kv[1], true } for _, qualifier := range qualifiers { if strings.HasPrefix(text, qualifier+":") { return text[:len(qualifier)], text[len(qualifier)+1:], true } } return "", "", false } func fields(text string) []string { var f []string var quotes bool var last int for idx, char := range text { if char == '"' { quotes = !quotes continue } if char == ' ' { if quotes { continue } f = append(f, text[last:idx]) last = idx + 1 } } f = append(f, strings.TrimSpace(text[last:])) return f } func trim(text string) string { return strings.TrimPrefix(strings.TrimSuffix(strings.TrimSpace(text), `"`), `"`) }