summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2024-10-08 17:04:30 +0200
committerxengineering <me@xengineering.eu>2024-10-08 17:04:30 +0200
commit2e326d354a536ec8626809c9fe9b411d05e79c46 (patch)
tree0f4415c6786635c8eee141e411520555ec0d0752
parentb03cf32bef7e34c4886a3b7300ffc0132b310a5b (diff)
downloadsoundbox-app-2e326d354a536ec8626809c9fe9b411d05e79c46.tar
soundbox-app-2e326d354a536ec8626809c9fe9b411d05e79c46.tar.zst
soundbox-app-2e326d354a536ec8626809c9fe9b411d05e79c46.zip
Use only one Config struct
This commit switches from a GlobalConfig struct with named sub-structs to a single struct definition with anonymous sub-structs. The advantage is that there are not so many names the reader has to understand. A custom UnmarshalJSON() function on the Config struct level ensures that the error checking can be embedded into the parsing process and native Go types like net.HardwareAddr can be used in the struct definition while the string-based struct for JSON unmarshaling is an implementation detail of the custom UnmarshalJSON() function. In general the user of this type and its method only has to parse the config with json.Unmarshal(), handle error at this step and can rely on validated configuration data with native Go types from that point on.
-rw-r--r--config.go73
-rw-r--r--main.go4
2 files changed, 48 insertions, 29 deletions
diff --git a/config.go b/config.go
index e187827..d04c423 100644
--- a/config.go
+++ b/config.go
@@ -10,62 +10,81 @@ import (
const configPathRelative = `.config/soundbox/config.json`
-type MacAddress net.HardwareAddr
+type Config struct {
+ Soundboxes []struct {
+ Name string
+ Mac net.HardwareAddr
+ }
+ URLs []struct {
+ Name string
+ Url string
+ }
+}
-func (m *MacAddress) UnmarshalJSON(data []byte) error {
- var macStr string
- err := json.Unmarshal(data, &macStr)
- if err != nil {
- return err
+func (config *Config) UnmarshalJSON(data []byte) error {
+ var buffer struct {
+ Soundboxes []struct {
+ Name string
+ Mac string
+ }
+ URLs []struct {
+ Name string
+ Url string
+ }
}
- hwAddr, err := net.ParseMAC(macStr)
+ err := json.Unmarshal(data, &buffer)
if err != nil {
return err
}
- *m = MacAddress(hwAddr)
- return nil
-}
+ parsed := Config{}
-type SoundboxConfig struct {
- Name string `json:"name"`
- Mac MacAddress `json:"mac"`
-}
+ for _, soundbox := range buffer.Soundboxes {
+ hwAddr, err := net.ParseMAC(soundbox.Mac)
+ if err != nil {
+ return err
+ }
+ parsed.Soundboxes = append(parsed.Soundboxes, struct {
+ Name string
+ Mac net.HardwareAddr
+ }{soundbox.Name, hwAddr})
+ }
-type URLConfig struct {
- Name string `json:"name"`
- Url string `json:"url"`
-}
+ for _, url := range buffer.URLs {
+ parsed.URLs = append(parsed.URLs, struct {
+ Name string
+ Url string
+ }{url.Name, url.Url})
+ }
-type GlobalConfig struct {
- Soundboxes []SoundboxConfig `json:"soundboxes"`
- URLs []URLConfig `json:"urls"`
+ *config = parsed
+ return nil
}
-func loadConfig() (GlobalConfig, error) {
+func loadConfig() (Config, error) {
home, err := os.UserHomeDir()
if err != nil {
- return GlobalConfig{}, err
+ return Config{}, err
}
path := filepath.Join(home, configPathRelative)
file, err := os.Open(path)
if err != nil {
- return GlobalConfig{}, err
+ return Config{}, err
}
defer file.Close()
bytes, err := io.ReadAll(file)
if err != nil {
- return GlobalConfig{}, err
+ return Config{}, err
}
- var config GlobalConfig
+ var config Config
err = json.Unmarshal(bytes, &config)
if err != nil {
- return GlobalConfig{}, err
+ return Config{}, err
}
return config, nil
diff --git a/main.go b/main.go
index 8302155..20ee049 100644
--- a/main.go
+++ b/main.go
@@ -38,7 +38,7 @@ func main() {
type State struct {
sync.Mutex
- Config GlobalConfig
+ Config Config
Theme *material.Theme
Title string
UrlEditor widget.Editor
@@ -53,7 +53,7 @@ type Ui struct {
State State
}
-func NewUi(config GlobalConfig) *Ui {
+func NewUi(config Config) *Ui {
ui := Ui{}
ui.State.Config = config