77 "os"
88 "path/filepath"
99 "reflect"
10+ "strconv"
1011 "strings"
1112
1213 "github.com/rsteube/carapace/pkg/xdg"
@@ -22,34 +23,60 @@ func (c configMap) Keys() []string {
2223 return keys
2324}
2425
25- type Field struct {
26- Name string
27- Description string
28- Style string
29- Tag string
30- }
31-
32- func (c configMap ) Fields (name string ) ([]Field , error ) {
26+ // func (c configMap) Fields(name string, styled bool) ([]string, error) {
27+ // if i, ok := c[name]; ok {
28+ // fields := make([]string, 0)
29+ // t := reflect.TypeOf(i).Elem()
30+ // for index := 0; index < t.NumField(); index++ {
31+ // field := t.Field(index)
32+ // style := ""
33+ // if styled {
34+ // if field.Type.Name() != "string" {
35+ // return nil, fmt.Errorf("invalid field type [name: '%v', type: '%v']", field.Name, field.Type.Name())
36+ // }
37+ // v := reflect.ValueOf(i).Elem()
38+ // style = v.FieldByName(field.Name).String()
39+ // }
40+ // fields = append(fields, field.Name, field.Tag.Get("desc"), style)
41+ // }
42+ // return fields, nil
43+ // }
44+ // return nil, fmt.Errorf("unknown config: '%v'", name)
45+ // }
46+
47+ func (c configMap ) Fields (name string , styled bool ) ([]Field , error ) {
3348 if i , ok := c [name ]; ok {
3449 fields := make ([]Field , 0 )
3550 t := reflect .TypeOf (i ).Elem ()
3651 v := reflect .ValueOf (i ).Elem ()
3752 for index := 0 ; index < t .NumField (); index ++ {
3853 field := t .Field (index )
39- if field .Type .Name () != "string" {
54+ if styled && field .Type .Name () != "string" {
4055 return nil , fmt .Errorf ("invalid field type [name: '%v', type: '%v']" , field .Name , field .Type .Name ())
4156 }
42- fields = append (fields , Field {field .Name , field .Tag .Get ("desc" ), v .FieldByName (field .Name ).String (), field .Tag .Get ("tag" )})
57+ fields = append (fields , Field {
58+ Name : field .Name ,
59+ Description : field .Tag .Get ("desc" ),
60+ Style : v .FieldByName (field .Name ).String (), // TODO only if styled
61+ Tag : field .Tag .Get ("tag" ),
62+ Type : field .Type ,
63+ })
4364 }
4465 return fields , nil
4566 }
4667 return nil , fmt .Errorf ("unknown config: '%v'" , name )
4768}
4869
4970var config = struct {
50- Styles configMap
71+ Configs configMap
72+ Styles configMap
5173}{
52- Styles : make (configMap ),
74+ Configs : make (configMap ),
75+ Styles : make (configMap ),
76+ }
77+
78+ func RegisterConfig (name string , i interface {}) {
79+ config .Configs [name ] = i
5380}
5481
5582func RegisterStyle (name string , i interface {}) {
@@ -60,6 +87,11 @@ func Load() error {
6087 if err := load ("styles" , config .Styles ); err != nil {
6188 return err
6289 }
90+
91+ // TODO duplicated, ok or improve?
92+ if err := load ("configs" , config .Configs ); err != nil {
93+ return err
94+ }
6395 return nil
6496}
6597
@@ -73,7 +105,7 @@ func load(name string, c configMap) error {
73105 return err
74106 }
75107
76- var unmarshalled map [string ]map [string ]string
108+ var unmarshalled map [string ]map [string ]interface {}
77109 if err := json .Unmarshal (content , & unmarshalled ); err != nil {
78110 return err
79111 }
@@ -83,7 +115,7 @@ func load(name string, c configMap) error {
83115 elem := reflect .ValueOf (s ).Elem ()
84116 for k , v := range value {
85117 if field := elem .FieldByName (k ); field != (reflect.Value {}) {
86- field .SetString ( v )
118+ field .Set ( reflect . ValueOf ( v ). Convert ( field . Type ()) )
87119 }
88120 }
89121 }
@@ -92,8 +124,16 @@ func load(name string, c configMap) error {
92124 return nil
93125}
94126
127+ func SetConfig (key , value string ) error {
128+ return set ("configs" , key , strings .Replace (value , "," , " " , - 1 ))
129+ }
130+
131+ func GetConfigs () []string { return config .Configs .Keys () }
132+ func GetConfigFields (name string ) ([]Field , error ) { return config .Configs .Fields (name , false ) }
133+ func GetConfigMap (name string ) interface {} { return config .Configs [name ] }
134+
95135func GetStyleConfigs () []string { return config .Styles .Keys () }
96- func GetStyleFields (name string ) ([]Field , error ) { return config .Styles .Fields (name ) }
136+ func GetStyleFields (name string ) ([]Field , error ) { return config .Styles .Fields (name , true ) }
97137func SetStyle (key , value string ) error {
98138 return set ("styles" , key , strings .Replace (value , "," , " " , - 1 ))
99139}
@@ -116,7 +156,7 @@ func set(name, key, value string) error {
116156 content = []byte ("{}" )
117157 }
118158
119- var config map [string ]map [string ]string
159+ var config map [string ]map [string ]interface {}
120160 if err := json .Unmarshal (content , & config ); err != nil {
121161 return err
122162 }
@@ -125,18 +165,33 @@ func set(name, key, value string) error {
125165 return errors .New ("invalid key" )
126166 } else {
127167 if _ , ok := config [splitted [0 ]]; ! ok {
128- config [splitted [0 ]] = make (map [string ]string , 0 )
168+ config [splitted [0 ]] = make (map [string ]interface {} , 0 )
129169 }
130170 if strings .TrimSpace (value ) == "" {
131171 delete (config [splitted [0 ]], splitted [1 ])
132172 } else {
133- config [splitted [0 ]][splitted [1 ]] = value
173+ switch reflect .TypeOf (config [splitted [0 ]][splitted [1 ]]).Kind () {
174+ case reflect .Int :
175+ intValue , err := strconv .Atoi (value )
176+ if err != nil {
177+ return err
178+ }
179+ config [splitted [0 ]][splitted [1 ]] = intValue
180+
181+ case reflect .String :
182+ config [splitted [0 ]][splitted [1 ]] = value
183+
184+ case reflect .Slice :
185+ // TODO
186+ }
134187 }
135188 }
136189
137190 marshalled , err := json .MarshalIndent (config , "" , " " )
138191 if err != nil {
139192 return err
140193 }
141- return os .WriteFile (file , marshalled , os .ModePerm )
194+ os .WriteFile (file , marshalled , os .ModePerm )
195+
196+ return nil
142197}
0 commit comments