page.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package qs
  2. import (
  3. "net/http"
  4. "net/url"
  5. )
  6. // Page represents a combination of pagination, filter and sort parameters for, most likely, a database query.
  7. type Page struct {
  8. Pagination *Pagination `json:"pagination"`
  9. Filters Filters `json:"filters,omitempty"`
  10. Sorts Sorts `json:"sorts,omitempty"`
  11. }
  12. // ReadPageOptions configures the behaviour of ReadPage.
  13. type ReadPageOptions struct {
  14. Pagination *ReadPaginationOptions
  15. Filter *ReadFiltersOptions
  16. Sort *ReadSortsOptions
  17. }
  18. // ReadPage parses URL values into a convenient Page struct.
  19. func ReadPage(values url.Values, opt *ReadPageOptions) (*Page, error) {
  20. opt = initPageOptions(opt)
  21. pag, err := ReadPagination(values, opt.Pagination)
  22. if err != nil {
  23. return nil, err
  24. }
  25. filters, err := ReadFilters(values, opt.Filter)
  26. if err != nil {
  27. return nil, err
  28. }
  29. sorts, err := ReadSorts(values, opt.Sort)
  30. if err != nil {
  31. return nil, err
  32. }
  33. page := &Page{
  34. Pagination: pag,
  35. Filters: filters,
  36. Sorts: sorts,
  37. }
  38. return page, nil
  39. }
  40. // ReadRequestPage parses a request's query string into a convenient Page struct.
  41. // This function always returns a value if it does not encounter an error.
  42. func ReadRequestPage(req *http.Request, opt *ReadPageOptions) (*Page, error) {
  43. return ReadPage(req.URL.Query(), opt)
  44. }
  45. // ReadStringPage parses a query string literal into a convenient Page struct.
  46. // This function always returns a value if it does not encounter an error.
  47. func ReadStringPage(qs string, opt *ReadPageOptions) (*Page, error) {
  48. values, err := url.ParseQuery(qs)
  49. if err != nil {
  50. return nil, err
  51. }
  52. return ReadPage(values, opt)
  53. }
  54. func initPageOptions(opt *ReadPageOptions) *ReadPageOptions {
  55. def := &ReadPageOptions{}
  56. if opt != nil {
  57. def.Pagination = initPaginationOptions(opt.Pagination)
  58. def.Filter = initFiltersOptions(opt.Filter)
  59. def.Sort = initSortsOptions(opt.Sort)
  60. }
  61. return def
  62. }