blob: 3b26013d767531855c4f8a0a3478241cfed14ca1 [file] [log] [blame]
Ash Wilsonc8e68872014-09-16 10:36:56 -04001package pagination
2
3import (
4 "github.com/mitchellh/mapstructure"
5 "github.com/rackspace/gophercloud"
6)
7
8// LinkedPageBase may be embedded to implement a page that provides navigational "Next" and "Previous" links within its result.
9type LinkedPageBase LastHTTPResponse
10
11// NextPageURL extracts the pagination structure from a JSON response and returns the "next" link, if one is present.
12// It assumes that the links are available in a "links" element of the top-level response object.
13// If this is not the case, override NextPageURL on your result type.
14func (current LinkedPageBase) NextPageURL() (string, error) {
15 type response struct {
16 Links struct {
17 Next *string `mapstructure:"next,omitempty"`
18 } `mapstructure:"links"`
19 }
20
21 var r response
22 err := mapstructure.Decode(current.Body, &r)
23 if err != nil {
24 return "", err
25 }
26
27 if r.Links.Next == nil {
28 return "", nil
29 }
30
31 return *r.Links.Next, nil
32}
33
34// NewLinkedPager creates a Pager that uses a "links" element in the JSON response to locate the next page.
35func NewLinkedPager(client *gophercloud.ServiceClient, initialURL string, createPage func(resp LastHTTPResponse) Page) Pager {
36 fetchNextPage := func(url string) (Page, error) {
37 resp, err := Request(client, url)
38 if err != nil {
39 return nil, err
40 }
41
42 cp, err := RememberHTTPResponse(resp)
43 if err != nil {
44 return nil, err
45 }
46
47 return createPage(cp), nil
48 }
49
50 return Pager{
51 initialURL: initialURL,
52 fetchNextPage: fetchNextPage,
53 }
54}