| 
					
				 | 
			
			
				@@ -0,0 +1,79 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package connection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"errors" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"fmt" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"github.com/samber/lo" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"math" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type Connection[T 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 errors.New("illegal arguments: only one of `after` or `before` can be used at a time") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if len(c.Edges) == 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		c.PageInfo = new(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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |