select.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package main
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. intdevice "netdome.biz/paul/qmk-rgb/internal/device"
  7. )
  8. // selectDevice resolves the --device selector against the discovered
  9. // keyboards. An empty selector picks the only keyboard when exactly one is
  10. // connected and fails otherwise, so commands never silently target the wrong
  11. // keyboard.
  12. func selectDevice(devices []intdevice.Device, selector string) (intdevice.Device, error) {
  13. if len(devices) == 0 {
  14. return intdevice.Device{}, fmt.Errorf("no QMK keyboard found")
  15. }
  16. if selector == "" {
  17. if len(devices) > 1 {
  18. return intdevice.Device{}, fmt.Errorf(
  19. "multiple QMK keyboards found, use --device to select:\n%s",
  20. formatDeviceList(devices))
  21. }
  22. return devices[0], nil
  23. }
  24. invalid := fmt.Errorf("invalid --device %q: expected a keyboard number\n%s",
  25. selector, formatDeviceList(devices))
  26. index, err := strconv.Atoi(selector)
  27. if err != nil {
  28. return intdevice.Device{}, invalid
  29. }
  30. if index < 1 || index > len(devices) {
  31. return intdevice.Device{}, invalid
  32. }
  33. return devices[index-1], nil
  34. }
  35. // formatDeviceList renders the selectable keyboards with the numbers that
  36. // --device accepts.
  37. func formatDeviceList(devices []intdevice.Device) string {
  38. var b strings.Builder
  39. for _, d := range devices {
  40. name := d.Name
  41. if name == "" {
  42. name = "Unknown QMK keyboard"
  43. }
  44. fmt.Fprintf(&b, " %d %s VID=0x%04x PID=0x%04x %s\n",
  45. d.Index, name, d.VendorID, d.ProductID, d.Path)
  46. }
  47. return b.String()
  48. }