package model import ( "encoding/json" "fmt" "git.beejay.kim/Craft/Api/connection" "github.com/samber/lo" "math" ) type Connection[T connection.Cursor] struct { Edges []T `json:"edges"` PageInfo *PageInfo `json:"page_info"` } func (c *Connection[T]) Reverse() { c.Edges = lo.Reverse[T](c.Edges) } func (c *Connection[T]) Grain(after, before *string) error { if after != nil && before != nil { return fmt.Errorf("illegal agruments: only one of `after` or `before` can be used at a time") } if len(c.Edges) == 0 { c.PageInfo = &PageInfo{} return nil } edges := lo.FlatMap[T, string](c.Edges, func(item T, _ int) []string { return []string{item.Cursor()} }) c.PageInfo = &PageInfo{ StartCursor: lo.ToPtr(edges[0]), EndCursor: lo.ToPtr(edges[(len(edges) - 1)]), } if after != nil { if idx := lo.IndexOf(edges, *after); idx != -1 { c.Edges = lo.Slice[T](c.Edges, idx+1, math.MaxUint32) } } if before != nil { if idx := lo.IndexOf(edges, *before); idx != -1 { c.Edges = lo.Subset[T](c.Edges, -idx, math.MaxUint32) } } return nil } func (c *Connection[T]) Slice(first, last *int) error { if first != nil && last != nil { return fmt.Errorf("illegal agruments: only one of `first` or `last` can be used at a time") } if first != nil { c.Edges = lo.Slice[T](c.Edges, 0, *first) } if last != nil { c.Edges = lo.Subset[T](c.Edges, -*last, math.MaxUint32) } if len(c.Edges) < 1 { c.PageInfo.HasPreviousPage = c.PageInfo.StartCursor != nil c.PageInfo.HasNextPage = c.PageInfo.EndCursor != nil c.PageInfo.StartCursor = nil c.PageInfo.EndCursor = nil } else { c.PageInfo.HasPreviousPage = !(*c.PageInfo.StartCursor == c.Edges[0].Cursor()) c.PageInfo.HasNextPage = !(*c.PageInfo.EndCursor == c.Edges[len(c.Edges)-1].Cursor()) c.PageInfo.StartCursor = lo.ToPtr(c.Edges[0].Cursor()) c.PageInfo.EndCursor = lo.ToPtr(c.Edges[len(c.Edges)-1].Cursor()) } return nil } func (c Connection[T]) Marshal() ([]byte, error) { return json.Marshal(c.Edges) } func (c *Connection[T]) Unmarshal(data []byte) error { return json.Unmarshal(data, &c.Edges) } func (c Connection[T]) Key() string { var zero []T return fmt.Sprintf("connection-edges-%T", zero) }