diff --git a/pkg/config/parser.go b/pkg/config/parser.go index 6e10169..433ed9d 100644 --- a/pkg/config/parser.go +++ b/pkg/config/parser.go @@ -26,12 +26,12 @@ type Controller struct { // Config represents the entire tellstick.conf structure type Config struct { - User string `json:"user,omitempty"` - Group string `json:"group,omitempty"` - DevicePath string `json:"devicePath,omitempty"` - IgnoreControllerConfirmation int `json:"ignoreControllerConfirmation,omitempty"` - Controllers []Controller `json:"controllers"` - Devices []Device `json:"devices"` + User string `json:"user,omitempty"` + Group string `json:"group,omitempty"` + DevicePath string `json:"devicePath,omitempty"` + IgnoreControllerConfirmation int `json:"ignoreControllerConfirmation,omitempty"` + Controllers []Controller `json:"controllers"` + Devices []Device `json:"devices"` } // Parser handles parsing and writing tellstick.conf files @@ -64,7 +64,7 @@ func (p *Parser) Parse() (*Config, error) { for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) - + // Skip empty lines and comments if line == "" || strings.HasPrefix(line, "#") { continue @@ -101,12 +101,12 @@ func (p *Parser) Parse() (*Config, error) { } // Section detection - if strings.HasPrefix(line, "controller") { + if strings.HasPrefix(line, "controller {") || strings.HasPrefix(line, "controller{") { currentSection = "controller" currentController = &Controller{} continue } - if strings.HasPrefix(line, "device") { + if strings.HasPrefix(line, "device {") || strings.HasPrefix(line, "device{") { currentSection = "device" currentDevice = &Device{ Parameters: make(map[string]string), @@ -134,7 +134,7 @@ func (p *Parser) Parse() (*Config, error) { if len(parts) == 2 { key := strings.TrimSpace(parts[0]) value := strings.Trim(strings.TrimSpace(parts[1]), "\"") - + switch key { case "id": fmt.Sscanf(value, "%d", ¤tDevice.ID) @@ -149,13 +149,13 @@ func (p *Parser) Parse() (*Config, error) { } } } - + if currentSection == "controller" && currentController != nil { parts := strings.SplitN(line, "=", 2) if len(parts) == 2 { key := strings.TrimSpace(parts[0]) value := strings.Trim(strings.TrimSpace(parts[1]), "\"") - + switch key { case "id": fmt.Sscanf(value, "%d", ¤tController.ID) @@ -200,7 +200,7 @@ func (p *Parser) Write(config *Config) error { if config.IgnoreControllerConfirmation > 0 { fmt.Fprintf(w, "ignoreControllerConfirmation = %d\n", config.IgnoreControllerConfirmation) } - + w.WriteString("\n") // Write controllers @@ -228,12 +228,12 @@ func (p *Parser) Write(config *Config) error { if dev.Model != "" { fmt.Fprintf(w, " model = \"%s\"\n", dev.Model) } - + // Write parameters for key, value := range dev.Parameters { fmt.Fprintf(w, " %s = \"%s\"\n", key, value) } - + w.WriteString("}\n\n") } diff --git a/pkg/config/parser_test.go b/pkg/config/parser_test.go new file mode 100644 index 0000000..9e99d22 --- /dev/null +++ b/pkg/config/parser_test.go @@ -0,0 +1,60 @@ +package config + +import ( + "os" + "path/filepath" + "testing" +) + +func TestParserControllerDetection(t *testing.T) { + sampleConfig := `user = "root" + group = "plugdev" + device { + id = 5 + name = "TF_OFFICE_DESK" + controller = 0 + protocol = "arctech" + model = "selflearning-switch" + parameters { + house = "12168864" + unit = "11" + } + } + controller { + id = 1 + type = 2 + serial = "AE01DHRN" + } + ` + + dir := t.TempDir() + cfgPath := filepath.Join(dir, "tellstick.conf") + if err := os.WriteFile(cfgPath, []byte(sampleConfig), 0o600); err != nil { + t.Fatalf("failed writing sample config: %v", err) + } + + parser := NewParser(cfgPath) + cfg, err := parser.Parse() + if err != nil { + t.Fatalf("parse failed: %v", err) + } + + if got, want := len(cfg.Controllers), 1; got != want { + t.Fatalf("expected %d controller, got %d", want, got) + } + ctrl := cfg.Controllers[0] + if ctrl.ID != 1 || ctrl.Serial != "AE01DHRN" { + t.Fatalf("unexpected controller parsed: %+v", ctrl) + } + + if got, want := len(cfg.Devices), 1; got != want { + t.Fatalf("expected %d device, got %d", want, got) + } + dev := cfg.Devices[0] + if dev.Name != "TF_OFFICE_DESK" { + t.Fatalf("unexpected device parsed: %+v", dev) + } + if val := dev.Parameters["controller"]; val != "0" { + t.Fatalf("expected controller parameter stored, got %q", val) + } +}