github.com/Files-com/files-sdk-go/v3@v3.1.81/iter.go (about)

     1  package files_sdk
     2  
     3  import (
     4  	"github.com/Files-com/files-sdk-go/v3/lib"
     5  )
     6  
     7  type ListParams struct {
     8  	Page     int64  `json:"page,omitempty" url:"page,omitempty" required:"false"`
     9  	PerPage  int64  `json:"per_page,omitempty" url:"per_page,omitempty" required:"false"`
    10  	Cursor   string `json:"cursor,omitempty" url:"cursor,omitempty" required:"false"`
    11  	MaxPages int64  `json:"-" url:"-"`
    12  }
    13  
    14  // ListParamsContainer is a general interface for which all list parameter
    15  // structs should comply. They achieve this by embedding a ListParams struct
    16  // and inheriting its implementation of this interface.
    17  type ListParamsContainer interface {
    18  	GetListParams() *ListParams
    19  }
    20  
    21  // GetListParams returns a ListParams struct (itself). It exists because any
    22  // structs that embed ListParams will inherit it, and thus implement the
    23  // ListParamsContainer interface.
    24  func (p *ListParams) GetListParams() *ListParams {
    25  	return p
    26  }
    27  
    28  type OnPageError func(error) (*[]interface{}, error)
    29  type Query func(params lib.Values, opts ...RequestResponseOption) (*[]interface{}, string, error)
    30  
    31  type IterI interface {
    32  	Next() bool
    33  	Current() interface{}
    34  	Err() error
    35  }
    36  
    37  var _ IterI = (*Iter)(nil)
    38  
    39  type TypedIterI[T any] interface {
    40  	Next() bool
    41  	Current() interface{}
    42  	Resource() T
    43  	Err() error
    44  }
    45  
    46  type IterPagingI interface {
    47  	IterI
    48  	EOFPage() bool
    49  }
    50  
    51  var _ IterPagingI = (*Iter)(nil)
    52  
    53  type ResourceIterator interface {
    54  	Iterate(interface{}, ...RequestResponseOption) (IterI, error)
    55  }
    56  
    57  type ReloadIterator interface {
    58  	Reload(opts ...RequestResponseOption) IterI
    59  }
    60  
    61  var _ ReloadIterator = (*Iter)(nil)
    62  
    63  type ResourceLoader interface {
    64  	LoadResource(interface{}, ...RequestResponseOption) (interface{}, error)
    65  }
    66  
    67  type Identifier interface {
    68  	Identifier() interface{}
    69  }
    70  
    71  type Iterable interface {
    72  	Iterable() bool
    73  }
    74  
    75  type Iter struct {
    76  	Query
    77  	ListParams   ListParamsContainer
    78  	Params       []interface{}
    79  	CurrentIndex int
    80  	Values       *[]interface{}
    81  	Cursor       string
    82  	Error        error
    83  	OnPageError
    84  	requestResponseOptions []RequestResponseOption
    85  }
    86  
    87  // Err returns the error, if any,
    88  // that caused the Iter to stop.
    89  // It must be inspected
    90  // after Next returns false.
    91  func (i *Iter) Err() error {
    92  	return i.Error
    93  }
    94  
    95  func (i *Iter) Current() interface{} {
    96  	return (*i.Values)[i.CurrentIndex]
    97  }
    98  
    99  func (i *Iter) GetParams() *ListParams {
   100  	return i.ListParams.GetListParams()
   101  }
   102  
   103  func (i *Iter) ExportParams() (lib.ExportValues, error) {
   104  	p := lib.Params{Params: i.GetParams()}
   105  	paramValues, err := p.ToValues()
   106  	if err != nil {
   107  		return lib.ExportValues{}, err
   108  	}
   109  	listParamValues, err := lib.Params{Params: i.ListParams}.ToValues()
   110  
   111  	if err != nil {
   112  		return lib.ExportValues{}, err
   113  	}
   114  
   115  	for key, value := range paramValues {
   116  		listParamValues.Set(key, value[0])
   117  	}
   118  
   119  	if i.GetCursor() != "" {
   120  		listParamValues.Del("page")
   121  	}
   122  
   123  	return lib.ExportValues{Values: listParamValues}, nil
   124  }
   125  
   126  func (i *Iter) GetPage() bool {
   127  	if i.GetParams().MaxPages != 0 && i.GetParams().Page == i.GetParams().MaxPages {
   128  		return false
   129  	}
   130  
   131  	i.CurrentIndex = 0
   132  
   133  	i.GetParams().Page += 1
   134  	if i.GetParams().Page == 2 && i.Cursor == "" {
   135  		return false
   136  	}
   137  	params, _ := i.ExportParams()
   138  	i.Values, i.Cursor, i.Error = i.Query(params, i.requestResponseOptions...)
   139  	i.SetCursor(i.Cursor)
   140  	if i.Error != nil && i.OnPageError != nil {
   141  		i.Values, i.Error = i.OnPageError(i.Error)
   142  	}
   143  	return i.Error == nil && len(*i.Values) != 0
   144  }
   145  
   146  func (i *Iter) EOFPage() bool {
   147  	return len(*i.Values) == i.CurrentIndex+1
   148  }
   149  
   150  func (i *Iter) Paging() bool {
   151  	return true
   152  }
   153  
   154  func (i *Iter) GetCursor() string {
   155  	return i.GetParams().Cursor
   156  }
   157  
   158  func (i *Iter) SetCursor(cursor string) {
   159  	i.GetParams().Cursor = cursor
   160  	i.Cursor = cursor
   161  }
   162  
   163  // Next iterates the results in i.Current() or i.`ResourceName`().
   164  // It returns true until there are no results remaining.
   165  // To adjust the number of results set ListParams.PerPage.
   166  // To have it auto-paginate set ListParams.MaxPages, default is 1.
   167  //
   168  // To iterate over all results use the following pattern.
   169  //
   170  //	for i.Next() {
   171  //	  i.Current()
   172  //	}
   173  func (i *Iter) Next() bool {
   174  	if i.Values == nil {
   175  		return i.GetPage() && len(*i.Values) > 0
   176  	} else if len(*i.Values) > i.CurrentIndex+1 {
   177  		i.CurrentIndex += 1
   178  		return true
   179  	}
   180  
   181  	if i.EOFPage() {
   182  		return i.GetPage()
   183  	}
   184  
   185  	return false
   186  }
   187  
   188  func (i *Iter) NextPage() bool {
   189  	return i.Cursor != ""
   190  }
   191  
   192  // Reload ignores any id passed in and creates a new reset Iter
   193  func (i *Iter) Reload(opts ...RequestResponseOption) IterI {
   194  	newIter := *i
   195  	newIter.ListParams = &ListParams{}
   196  	newIter.requestResponseOptions = opts
   197  	return &newIter
   198  }