1package iterator
2
3import (
4 "context"
5 "strconv"
6
7 "code.gitea.io/sdk/gitea"
8)
9
10type issueIterator struct {
11 page int
12 lastPage bool
13 index int
14 cache []*gitea.Issue
15}
16
17func newIssueIterator() *issueIterator {
18 ii := &issueIterator{}
19 ii.Reset()
20 return ii
21}
22
23func (ii *issueIterator) Next(ctx context.Context, conf config) (bool, error) {
24 // first query
25 if ii.cache == nil {
26 return ii.getNext(ctx, conf)
27 }
28
29 // move cursor index
30 if ii.index < len(ii.cache)-1 {
31 ii.index++
32 return true, nil
33 }
34
35 return ii.getNext(ctx, conf)
36}
37
38func (ii *issueIterator) Value() *gitea.Issue {
39 return ii.cache[ii.index]
40}
41
42func (ii *issueIterator) getNext(ctx context.Context, conf config) (bool, error) {
43 if ii.lastPage {
44 return false, nil
45 }
46
47 ctx, cancel := context.WithTimeout(ctx, conf.timeout)
48 defer cancel()
49 conf.gc.SetContext(ctx)
50
51 issues, resp, err := conf.gc.ListRepoIssues(
52 conf.owner,
53 conf.project,
54 gitea.ListIssueOption{
55 ListOptions: gitea.ListOptions{
56 Page: ii.page,
57 PageSize: conf.capacity,
58 },
59 State: gitea.StateAll,
60 Type: gitea.IssueTypeIssue,
61 },
62 )
63
64 if err != nil {
65 ii.Reset()
66 return false, err
67 }
68
69 total, err := strconv.Atoi(resp.Header.Get("X-Total-Count"))
70 if err != nil {
71 ii.Reset()
72 return false, err
73 }
74
75 if total <= ii.page*conf.capacity {
76 ii.lastPage = true
77 }
78
79 // if repository doesn't have any issues
80 if len(issues) == 0 {
81 return false, nil
82 }
83
84 ii.cache = issues
85 ii.index = 0
86 ii.page++
87
88 return true, nil
89}
90
91func (ii *issueIterator) Reset() {
92 ii.index = -1
93 ii.page = 1
94 ii.lastPage = false
95 ii.cache = nil
96}