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