@@ -3,6 +3,7 @@ package config
33import (
44 "gopkg.in/yaml.v2"
55 "io/ioutil"
6+ "log"
67 "os"
78 "reflect"
89 "strings"
@@ -11,8 +12,9 @@ import (
1112type ModelType int
1213
1314const (
14- configName = "config.yaml"
15- LoopBackKey = "@"
15+ configName = "config.yaml"
16+ LoopBackKey = "@"
17+ TipSeparator = ", "
1618
1719 TypeUnknown ModelType = iota
1820 TypeVector
@@ -58,13 +60,61 @@ func (n *Nest) AddScalar(paths []string, url string) {
5860 addScalar (n .Data , paths , url )
5961}
6062
63+ //alfred
64+ func (n * Nest ) ListWithPre (paths []string ) map [string ]string {
65+ switch len (paths ) {
66+ case 0 :
67+ return findMapPrefix (n .Data , "" )
68+ case 1 :
69+ return findMapPrefix (n .Data , paths [0 ])
70+ default :
71+ out , ok := getByPath (paths [:len (paths )- 1 ], n .Data )
72+ if ! ok {
73+ return nil
74+ }
75+ m , ok := out .(map [string ]interface {})
76+ if ! ok {
77+ return nil
78+ }
79+ return findMapPrefix (m , paths [len (paths )- 1 ])
80+
81+ }
82+
83+ return nil
84+ }
85+
86+ func findMapPrefix (m map [string ]interface {}, pre string ) map [string ]string {
87+ found := make (map [string ]string )
88+ for k , v := range m {
89+ if strings .HasPrefix (k , pre ) {
90+ switch typeOf (v ) {
91+ case TypeVector :
92+ found [k ] = extractKeys (v .(map [string ]interface {}))
93+ case TypeScalar :
94+ found [k ] = v .(string )
95+ }
96+ }
97+ }
98+ return found
99+ }
100+
101+ func extractKeys (m map [string ]interface {}) string {
102+ out := ""
103+ for k , _ := range m {
104+ out += k + TipSeparator
105+ }
106+ out = strings .TrimSuffix (out , TipSeparator )
107+ return out
108+ }
109+
61110func typeOf (i interface {}) ModelType {
62111 switch reflect .TypeOf (i ).Kind () {
63112 case reflect .Map :
64113 return TypeVector
65114 case reflect .String :
66115 return TypeScalar
67116 default :
117+ log .Print ("WARNNIG unknown type" + reflect .TypeOf (i ).Kind ().String ())
68118 return TypeUnknown
69119 }
70120}
@@ -131,31 +181,39 @@ func addScalar(m map[string]interface{}, paths []string, url string) map[string]
131181
132182//get the specified URL
133183func getScalar (paths []string , m map [string ]interface {}) (scalar string , ok bool ) {
134- if len (paths ) == 0 {
184+ if len (paths ) == 0 || len ( m ) == 0 {
135185 return
136186 }
137- value , got := m [ paths [ 0 ]]
138- if ! got {
187+ v , ok := getByPath ( paths , m )
188+ if ! ok {
139189 return
140190 }
141- switch typeOf (value ) {
191+ switch typeOf (v ) {
142192 case TypeScalar :
143- return value .(string ), true
193+ return v .(string ), true
144194 case TypeVector :
145- if len (paths ) == 1 {
146- v , ok := value .(map [string ]interface {})[LoopBackKey ]
147- if ok {
148- return v .(string ), true
149- } else {
150- return "" , false
151- }
195+ v , ok := v .(map [string ]interface {})[LoopBackKey ]
196+ if ok {
197+ return v .(string ), true
198+ } else {
199+ return "" , false
152200 }
153- return getScalar (paths [1 :], value .(map [string ]interface {}))
154201 default :
155202 return
156203 }
157204}
158205
206+ func getByPath (paths []string , m map [string ]interface {}) (out interface {}, ok bool ) {
207+ if len (paths ) == 0 || len (m ) == 0 {
208+ return
209+ }
210+ out , ok = m [paths [0 ]]
211+ if ! ok || len (paths ) == 1 {
212+ return
213+ }
214+ return getByPath (paths [1 :], out .(map [string ]interface {}))
215+ }
216+
159217//convert map[interface{}]intreface{} to map[string]interface{}
160218func toMapStringInterface (m map [interface {}]interface {}) map [string ]interface {} {
161219 nm := make (map [string ]interface {})
0 commit comments