1// +build codegen
2
3package api
4
5import (
6	"encoding/json"
7	"fmt"
8	"os"
9)
10
11// Paginator keeps track of pagination configuration for an API operation.
12type Paginator struct {
13	InputTokens  interface{} `json:"input_token"`
14	OutputTokens interface{} `json:"output_token"`
15	LimitKey     string      `json:"limit_key"`
16	MoreResults  string      `json:"more_results"`
17}
18
19// InputTokensString returns output tokens formatted as a list
20func (p *Paginator) InputTokensString() string {
21	str := p.InputTokens.([]string)
22	return fmt.Sprintf("%#v", str)
23}
24
25// OutputTokensString returns output tokens formatted as a list
26func (p *Paginator) OutputTokensString() string {
27	str := p.OutputTokens.([]string)
28	return fmt.Sprintf("%#v", str)
29}
30
31// used for unmarshaling from the paginators JSON file
32type paginationDefinitions struct {
33	*API
34	Pagination map[string]Paginator
35}
36
37// AttachPaginators attaches pagination configuration from filename to the API.
38func (a *API) AttachPaginators(filename string) error {
39	p := paginationDefinitions{API: a}
40
41	f, err := os.Open(filename)
42	defer f.Close()
43	if err != nil {
44		return err
45	}
46	err = json.NewDecoder(f).Decode(&p)
47	if err != nil {
48		return fmt.Errorf("failed to decode %s, err: %v", filename, err)
49	}
50
51	return p.setup()
52}
53
54// setup runs post-processing on the paginator configuration.
55func (p *paginationDefinitions) setup() error {
56	for n, e := range p.Pagination {
57		if e.InputTokens == nil || e.OutputTokens == nil {
58			continue
59		}
60		paginator := e
61
62		switch t := paginator.InputTokens.(type) {
63		case string:
64			paginator.InputTokens = []string{t}
65		case []interface{}:
66			toks := []string{}
67			for _, e := range t {
68				s := e.(string)
69				toks = append(toks, s)
70			}
71			paginator.InputTokens = toks
72		}
73		switch t := paginator.OutputTokens.(type) {
74		case string:
75			paginator.OutputTokens = []string{t}
76		case []interface{}:
77			toks := []string{}
78			for _, e := range t {
79				s := e.(string)
80				toks = append(toks, s)
81			}
82			paginator.OutputTokens = toks
83		}
84
85		if o, ok := p.Operations[n]; ok {
86			o.Paginator = &paginator
87		} else {
88			return fmt.Errorf("unknown operation for paginator, %s", n)
89		}
90	}
91
92	return nil
93}
94
95func enableStopOnSameToken(service string) bool {
96	switch service {
97	case "cloudwatchlogs":
98		return true
99	default:
100		return false
101	}
102}
103