connection.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package connection
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/samber/lo"
  6. "math"
  7. )
  8. type Connection[T Cursor] struct {
  9. Edges []T `json:"edges"`
  10. PageInfo *PageInfo `json:"page_info"`
  11. }
  12. func (c *Connection[T]) Reverse() {
  13. c.Edges = lo.Reverse[T](c.Edges)
  14. }
  15. func (c *Connection[T]) Grain(after, before *string) error {
  16. if after != nil && before != nil {
  17. return errors.New("illegal arguments: only one of `after` or `before` can be used at a time")
  18. }
  19. if len(c.Edges) == 0 {
  20. c.PageInfo = new(PageInfo)
  21. return nil
  22. }
  23. edges := lo.FlatMap[T, string](c.Edges, func(item T, _ int) []string {
  24. return []string{item.Cursor()}
  25. })
  26. c.PageInfo = &PageInfo{
  27. StartCursor: lo.ToPtr(edges[0]),
  28. EndCursor: lo.ToPtr(edges[(len(edges) - 1)]),
  29. }
  30. if after != nil {
  31. if idx := lo.IndexOf(edges, *after); idx != -1 {
  32. c.Edges = lo.Slice[T](c.Edges, idx+1, math.MaxUint32)
  33. }
  34. }
  35. if before != nil {
  36. if idx := lo.IndexOf(edges, *before); idx != -1 {
  37. c.Edges = lo.Subset[T](c.Edges, -idx, math.MaxUint32)
  38. }
  39. }
  40. return nil
  41. }
  42. func (c *Connection[T]) Slice(first, last *int) error {
  43. if first != nil && last != nil {
  44. return fmt.Errorf("illegal agruments: only one of `first` or `last` can be used at a time")
  45. }
  46. if first != nil {
  47. c.Edges = lo.Slice[T](c.Edges, 0, *first)
  48. }
  49. if last != nil {
  50. c.Edges = lo.Subset[T](c.Edges, -*last, math.MaxUint32)
  51. }
  52. if len(c.Edges) < 1 {
  53. c.PageInfo.HasPreviousPage = c.PageInfo.StartCursor != nil
  54. c.PageInfo.HasNextPage = c.PageInfo.EndCursor != nil
  55. c.PageInfo.StartCursor = nil
  56. c.PageInfo.EndCursor = nil
  57. } else {
  58. c.PageInfo.HasPreviousPage = !(*c.PageInfo.StartCursor == c.Edges[0].Cursor())
  59. c.PageInfo.HasNextPage = !(*c.PageInfo.EndCursor == c.Edges[len(c.Edges)-1].Cursor())
  60. c.PageInfo.StartCursor = lo.ToPtr(c.Edges[0].Cursor())
  61. c.PageInfo.EndCursor = lo.ToPtr(c.Edges[len(c.Edges)-1].Cursor())
  62. }
  63. return nil
  64. }