forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
at master 1.2 kB view raw
1package pagination 2 3import "context" 4 5type Page struct { 6 Offset int // where to start from 7 Limit int // number of items in a page 8} 9 10func FirstPage() Page { 11 return Page{ 12 Offset: 0, 13 Limit: 30, 14 } 15} 16 17type ctxKey struct{} 18 19func IntoContext(ctx context.Context, page Page) context.Context { 20 return context.WithValue(ctx, ctxKey{}, page) 21} 22 23func FromContext(ctx context.Context) Page { 24 if ctx == nil { 25 return FirstPage() 26 } 27 v := ctx.Value(ctxKey{}) 28 if v == nil { 29 return FirstPage() 30 } 31 page, ok := v.(Page) 32 if !ok { 33 return FirstPage() 34 } 35 return page 36} 37 38func (p Page) Previous() Page { 39 if p.Offset-p.Limit < 0 { 40 return FirstPage() 41 } else { 42 return Page{ 43 Offset: p.Offset - p.Limit, 44 Limit: p.Limit, 45 } 46 } 47} 48 49func (p Page) Next() Page { 50 return Page{ 51 Offset: p.Offset + p.Limit, 52 Limit: p.Limit, 53 } 54} 55 56func IterateAll[T any]( 57 fetch func(page Page) ([]T, error), 58 handle func(items []T) error, 59) error { 60 page := FirstPage() 61 for { 62 items, err := fetch(page) 63 if err != nil { 64 return err 65 } 66 67 err = handle(items) 68 if err != nil { 69 return err 70 } 71 if len(items) < page.Limit { 72 break 73 } 74 page = page.Next() 75 } 76 return nil 77}