cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm
leaflet
readability
golang
1package handlers
2
3import (
4 "fmt"
5 "reflect"
6 "strings"
7
8 "github.com/stormlightlabs/noteleaf/internal/store"
9)
10
11// ConfigHandler handles [store.Config]-related operations
12type ConfigHandler struct {
13 config *store.Config
14}
15
16// NewConfigHandler creates a new [ConfigHandler]
17func NewConfigHandler() (*ConfigHandler, error) {
18 config, err := store.LoadConfig()
19 if err != nil {
20 return nil, fmt.Errorf("failed to load config: %w", err)
21 }
22
23 return &ConfigHandler{config: config}, nil
24}
25
26// Get displays one or all configuration values
27func (h *ConfigHandler) Get(key string) error {
28 if key == "" {
29 return h.displayAll()
30 }
31
32 value, err := h.getConfigValue(key)
33 if err != nil {
34 return err
35 }
36
37 fmt.Printf("%s = %v\n", key, value)
38 return nil
39}
40
41// Set updates a configuration value
42func (h *ConfigHandler) Set(key, value string) error {
43 if err := h.setConfigValue(key, value); err != nil {
44 return err
45 }
46
47 if err := store.SaveConfig(h.config); err != nil {
48 return fmt.Errorf("failed to save config: %w", err)
49 }
50
51 fmt.Printf("Set %s = %s\n", key, value)
52 return nil
53}
54
55// Path displays the configuration file path
56func (h *ConfigHandler) Path() error {
57 path, err := store.GetConfigPath()
58 if err != nil {
59 return fmt.Errorf("failed to get config path: %w", err)
60 }
61
62 fmt.Println(path)
63 return nil
64}
65
66// Reset resets the configuration to defaults
67func (h *ConfigHandler) Reset() error {
68 h.config = store.DefaultConfig()
69
70 if err := store.SaveConfig(h.config); err != nil {
71 return fmt.Errorf("failed to save config: %w", err)
72 }
73
74 fmt.Println("Configuration reset to defaults")
75 return nil
76}
77
78func (h *ConfigHandler) displayAll() error {
79 v := reflect.ValueOf(*h.config)
80 t := reflect.TypeOf(*h.config)
81
82 for i := 0; i < v.NumField(); i++ {
83 field := t.Field(i)
84 value := v.Field(i)
85
86 tomlTag := field.Tag.Get("toml")
87 if tomlTag == "" {
88 continue
89 }
90
91 tagName := strings.Split(tomlTag, ",")[0]
92
93 switch value.Kind() {
94 case reflect.String:
95 if value.String() != "" {
96 fmt.Printf("%s = %q\n", tagName, value.String())
97 } else {
98 fmt.Printf("%s = \"\"\n", tagName)
99 }
100 case reflect.Bool:
101 fmt.Printf("%s = %t\n", tagName, value.Bool())
102 default:
103 fmt.Printf("%s = %v\n", tagName, value.Interface())
104 }
105 }
106
107 return nil
108}
109
110func (h *ConfigHandler) getConfigValue(key string) (any, error) {
111 v := reflect.ValueOf(*h.config)
112 t := reflect.TypeOf(*h.config)
113
114 for i := 0; i < v.NumField(); i++ {
115 field := t.Field(i)
116 tomlTag := field.Tag.Get("toml")
117 if tomlTag == "" {
118 continue
119 }
120
121 tagName := strings.Split(tomlTag, ",")[0]
122 if tagName == key {
123 return v.Field(i).Interface(), nil
124 }
125 }
126
127 return nil, fmt.Errorf("unknown config key: %s", key)
128}
129
130func (h *ConfigHandler) setConfigValue(key, value string) error {
131 v := reflect.ValueOf(h.config).Elem()
132 t := reflect.TypeOf(*h.config)
133
134 for i := 0; i < v.NumField(); i++ {
135 field := t.Field(i)
136 tomlTag := field.Tag.Get("toml")
137 if tomlTag == "" {
138 continue
139 }
140
141 tagName := strings.Split(tomlTag, ",")[0]
142 if tagName == key {
143 fieldValue := v.Field(i)
144
145 switch fieldValue.Kind() {
146 case reflect.String:
147 fieldValue.SetString(value)
148 case reflect.Bool:
149 boolVal := value == "true" || value == "1" || value == "yes"
150 fieldValue.SetBool(boolVal)
151 default:
152 return fmt.Errorf("unsupported field type for key %s", key)
153 }
154
155 return nil
156 }
157 }
158
159 return fmt.Errorf("unknown config key: %s", key)
160}