1package cache
2
3import (
4 "fmt"
5 "strings"
6)
7
8type Query struct {
9 Filters
10 OrderBy
11 OrderDirection
12}
13
14// ParseQuery parse a query DSL
15//
16// Ex: "status:open author:descartes sort:edit-asc"
17//
18// Supported filter fields and syntax are described in docs/queries.md
19//
20// Todo: write a complete doc
21func ParseQuery(query string) (*Query, error) {
22 fields := strings.Fields(query)
23
24 result := &Query{
25 OrderBy: OrderByCreation,
26 OrderDirection: OrderDescending,
27 }
28
29 sortingDone := false
30
31 for _, field := range fields {
32 split := strings.Split(field, ":")
33 if len(split) != 2 {
34 return nil, fmt.Errorf("can't parse \"%s\"", field)
35 }
36
37 switch split[0] {
38 case "status":
39 f, err := StatusFilter(split[1])
40 if err != nil {
41 return nil, err
42 }
43 result.Status = append(result.Status, f)
44
45 case "author":
46 f := AuthorFilter(split[1])
47 result.Author = append(result.Author, f)
48
49 case "label":
50 f := LabelFilter(split[1])
51 result.Label = append(result.Label, f)
52
53 case "no":
54 err := result.parseNoFilter(split[1])
55 if err != nil {
56 return nil, err
57 }
58
59 case "sort":
60 if sortingDone {
61 return nil, fmt.Errorf("multiple sorting")
62 }
63
64 err := result.parseSorting(split[1])
65 if err != nil {
66 return nil, err
67 }
68
69 sortingDone = true
70
71 default:
72 return nil, fmt.Errorf("unknow query field %s", split[0])
73 }
74 }
75
76 return result, nil
77}
78
79func (q *Query) parseNoFilter(query string) error {
80 switch query {
81 case "label":
82 q.NoFilters = append(q.NoFilters, NoLabelFilter())
83 default:
84 return fmt.Errorf("unknown \"no\" filter")
85 }
86
87 return nil
88}
89
90func (q *Query) parseSorting(query string) error {
91 switch query {
92 // default ASC
93 case "id-desc":
94 q.OrderBy = OrderById
95 q.OrderDirection = OrderDescending
96 case "id", "id-asc":
97 q.OrderBy = OrderById
98 q.OrderDirection = OrderAscending
99
100 // default DESC
101 case "creation", "creation-desc":
102 q.OrderBy = OrderByCreation
103 q.OrderDirection = OrderDescending
104 case "creation-asc":
105 q.OrderBy = OrderByCreation
106 q.OrderDirection = OrderAscending
107
108 // default DESC
109 case "edit", "edit-desc":
110 q.OrderBy = OrderByEdit
111 q.OrderDirection = OrderDescending
112 case "edit-asc":
113 q.OrderBy = OrderByEdit
114 q.OrderDirection = OrderAscending
115
116 default:
117 return fmt.Errorf("unknow sorting %s", query)
118 }
119
120 return nil
121}