package github import ( "net/http" "net/url" "strconv" "strings" ) type githubPagination struct { NextPage, PrevPage, FirstPage, LastPage int NextPageToken, Cursor, Before, After string } func parsePaginator(he http.Header) *githubPagination { r := &githubPagination{} if links, ok := he["Link"]; ok && len(links) > 0 { for link := range strings.SplitSeq(links[0], ",") { segments := strings.Split(strings.TrimSpace(link), ";") if len(segments) < 2 { continue } if !strings.HasPrefix(segments[0], "<") || !strings.HasSuffix(segments[0], ">") { continue } url, err := url.Parse(segments[0][1 : len(segments[0])-1]) if err != nil { continue } q := url.Query() if cursor := q.Get("cursor"); cursor != "" { for _, segment := range segments[1:] { switch strings.TrimSpace(segment) { case `rel="next"`: r.Cursor = cursor } } continue } page := q.Get("page") since := q.Get("since") before := q.Get("before") after := q.Get("after") if page == "" && before == "" && after == "" && since == "" { continue } if since != "" && page == "" { page = since } for _, segment := range segments[1:] { switch strings.TrimSpace(segment) { case `rel="next"`: if r.NextPage, err = strconv.Atoi(page); err != nil { r.NextPageToken = page } r.After = after case `rel="prev"`: r.PrevPage, _ = strconv.Atoi(page) r.Before = before case `rel="first"`: r.FirstPage, _ = strconv.Atoi(page) case `rel="last"`: r.LastPage, _ = strconv.Atoi(page) } } } } return r }