From 116ae769f1b6f9ec645561af1d603385b39fa025 Mon Sep 17 00:00:00 2001 From: Peter Marton Date: Mon, 2 Sep 2024 11:08:00 +0200 Subject: [PATCH] feat(pagination): add helpers (#1451) --- pkg/pagination/pagination.go | 59 ++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/pkg/pagination/pagination.go b/pkg/pagination/pagination.go index ea65d45b0..de02387ce 100644 --- a/pkg/pagination/pagination.go +++ b/pkg/pagination/pagination.go @@ -20,6 +20,31 @@ type Page struct { PageNumber int `json:"page"` } +// NewPage creates a new Page with the given pageNumber and pageSize. +func NewPage(pageNumber int, pageSize int) Page { + return Page{ + PageSize: pageSize, + PageNumber: pageNumber, + } +} + +// NewPageFromRef creates a new Page from pointers to pageNumber and pageSize. +// Useful for handling query parameters. +func NewPageFromRef(pageNumber *int, pageSize *int) Page { + pn := 0 + ps := 0 + + if pageNumber != nil { + pn = *pageNumber + } + + if pageSize != nil { + ps = *pageSize + } + + return NewPage(pn, ps) +} + func (p Page) Offset() int { return p.PageSize * (p.PageNumber - 1) } @@ -50,6 +75,40 @@ type PagedResponse[T any] struct { Items []T `json:"items"` } +// MapPagedResponse creates a new PagedResponse with the given page, totalCount and items. +func MapPagedResponse[Out any, In any](resp PagedResponse[In], m func(in In) Out) PagedResponse[Out] { + items := make([]Out, 0, len(resp.Items)) + for _, inItem := range resp.Items { + items = append(items, m(inItem)) + } + + return PagedResponse[Out]{ + Page: resp.Page, + TotalCount: resp.TotalCount, + Items: items, + } +} + +// MapPagedResponseError is similar to MapPagedResponse +// but it allows the mapping function to return an error. +func MapPagedResponseError[Out any, In any](resp PagedResponse[In], m func(in In) (Out, error)) (PagedResponse[Out], error) { + items := make([]Out, 0, len(resp.Items)) + for _, inItem := range resp.Items { + item, err := m(inItem) + if err != nil { + return PagedResponse[Out]{}, err + } + + items = append(items, item) + } + + return PagedResponse[Out]{ + Page: resp.Page, + TotalCount: resp.TotalCount, + Items: items, + }, nil +} + // Implement json.Marshaler interface to flatten the Page struct func (p PagedResponse[T]) MarshalJSON() ([]byte, error) { type Alias PagedResponse[T]