issue.go

 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}