1package connections
2
3import (
4 "fmt"
5 "github.com/MichaelMure/git-bug/graphql/models"
6 "github.com/cheekybits/genny/generic"
7)
8
9type NodeType generic.Type
10type EdgeType generic.Type
11type ConnectionType generic.Type
12
13type NodeTypeEdger func(value NodeType, offset int) Edge
14
15type NodeTypeConMaker func(
16 edges []EdgeType,
17 nodes []NodeType,
18 info models.PageInfo,
19 totalCount int) (ConnectionType, error)
20
21func NodeTypeCon(source []NodeType, edger NodeTypeEdger, conMaker NodeTypeConMaker, input models.ConnectionInput) (ConnectionType, error) {
22 var nodes []NodeType
23 var edges []EdgeType
24 var pageInfo models.PageInfo
25
26 emptyCon, _ := conMaker(edges, nodes, pageInfo, 0)
27
28 offset := 0
29
30 if input.After != nil {
31 for i, value := range source {
32 edge := edger(value, i)
33 if edge.GetCursor() == *input.After {
34 // remove all previous element including the "after" one
35 source = source[i+1:]
36 offset = i + 1
37 break
38 }
39 }
40 }
41
42 if input.Before != nil {
43 for i, value := range source {
44 edge := edger(value, i+offset)
45
46 if edge.GetCursor() == *input.Before {
47 // remove all after element including the "before" one
48 break
49 }
50
51 edges = append(edges, edge.(EdgeType))
52 nodes = append(nodes, value)
53 }
54 } else {
55 edges = make([]EdgeType, len(source))
56 nodes = source
57
58 for i, value := range source {
59 edges[i] = edger(value, i+offset).(EdgeType)
60 }
61 }
62
63 if input.First != nil {
64 if *input.First < 0 {
65 return emptyCon, fmt.Errorf("first less than zero")
66 }
67
68 if len(edges) > *input.First {
69 // Slice result to be of length first by removing edges from the end
70 edges = edges[:*input.First]
71 nodes = nodes[:*input.First]
72 pageInfo.HasNextPage = true
73 }
74 }
75
76 if input.Last != nil {
77 if *input.Last < 0 {
78 return emptyCon, fmt.Errorf("last less than zero")
79 }
80
81 if len(edges) > *input.Last {
82 // Slice result to be of length last by removing edges from the start
83 edges = edges[len(edges)-*input.Last:]
84 nodes = nodes[len(nodes)-*input.Last:]
85 pageInfo.HasPreviousPage = true
86 }
87 }
88
89 return conMaker(edges, nodes, pageInfo, len(source))
90}