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