...
1 package sortref
2
3 import (
4 "reflect"
5 "sort"
6 "strings"
7
8 "github.com/go-openapi/analysis/internal/flatten/normalize"
9 "github.com/go-openapi/spec"
10 )
11
12 var depthGroupOrder = []string{
13 "sharedParam", "sharedResponse", "sharedOpParam", "opParam", "codeResponse", "defaultResponse", "definition",
14 }
15
16 type mapIterator struct {
17 len int
18 mapIter *reflect.MapIter
19 }
20
21 func (i *mapIterator) Next() bool {
22 return i.mapIter.Next()
23 }
24
25 func (i *mapIterator) Len() int {
26 return i.len
27 }
28
29 func (i *mapIterator) Key() string {
30 return i.mapIter.Key().String()
31 }
32
33 func mustMapIterator(anyMap interface{}) *mapIterator {
34 val := reflect.ValueOf(anyMap)
35
36 return &mapIterator{mapIter: val.MapRange(), len: val.Len()}
37 }
38
39
40
41
42
43 func DepthFirst(in interface{}) []string {
44 iterator := mustMapIterator(in)
45 sorted := make([]string, 0, iterator.Len())
46 grouped := make(map[string]Keys, iterator.Len())
47
48 for iterator.Next() {
49 k := iterator.Key()
50 split := KeyParts(k)
51 var pk string
52
53 if split.IsSharedOperationParam() {
54 pk = "sharedOpParam"
55 }
56 if split.IsOperationParam() {
57 pk = "opParam"
58 }
59 if split.IsStatusCodeResponse() {
60 pk = "codeResponse"
61 }
62 if split.IsDefaultResponse() {
63 pk = "defaultResponse"
64 }
65 if split.IsDefinition() {
66 pk = "definition"
67 }
68 if split.IsSharedParam() {
69 pk = "sharedParam"
70 }
71 if split.IsSharedResponse() {
72 pk = "sharedResponse"
73 }
74 grouped[pk] = append(grouped[pk], Key{Segments: len(split), Key: k})
75 }
76
77 for _, pk := range depthGroupOrder {
78 res := grouped[pk]
79 sort.Sort(res)
80
81 for _, v := range res {
82 sorted = append(sorted, v.Key)
83 }
84 }
85
86 return sorted
87 }
88
89
90
91 type topmostRefs []string
92
93 func (k topmostRefs) Len() int { return len(k) }
94 func (k topmostRefs) Swap(i, j int) { k[i], k[j] = k[j], k[i] }
95 func (k topmostRefs) Less(i, j int) bool {
96 li, lj := len(strings.Split(k[i], "/")), len(strings.Split(k[j], "/"))
97 if li == lj {
98 return k[i] < k[j]
99 }
100
101 return li < lj
102 }
103
104
105 func TopmostFirst(refs []string) []string {
106 res := topmostRefs(refs)
107 sort.Sort(res)
108
109 return res
110 }
111
112
113 type RefRevIdx struct {
114 Ref spec.Ref
115 Keys []string
116 }
117
118
119 func ReverseIndex(schemas map[string]spec.Ref, basePath string) map[string]RefRevIdx {
120 collected := make(map[string]RefRevIdx)
121 for key, schRef := range schemas {
122
123
124 normalizedPath := normalize.Path(schRef, basePath)
125
126 entry, ok := collected[normalizedPath]
127 if ok {
128 entry.Keys = append(entry.Keys, key)
129 collected[normalizedPath] = entry
130
131 continue
132 }
133
134 collected[normalizedPath] = RefRevIdx{
135 Ref: schRef,
136 Keys: []string{key},
137 }
138 }
139
140 return collected
141 }
142
View as plain text