//go:build ignore // +build ignore package main import ( "encoding/hex" "encoding/json" "fmt" "io/ioutil" "os" "regexp" "strings" "text/template" "time" "golang.org/x/text/cases" "golang.org/x/text/language" "tinygo.org/x/bluetooth" ) type Service struct { Name string `json:"name"` Identifier string `json:"identifier"` UUID string `json:"uuid"` Source string `json:"source"` } func (s Service) VarName() string { str := strings.ReplaceAll(s.Name, "Service", "") // Remove non-alphanumeric characters. var nonAlphanumericRegex = regexp.MustCompile(`[^a-zA-Z0-9 ]+`) str = nonAlphanumericRegex.ReplaceAllString(str, "") str = cases.Title(language.Und, cases.NoLower).String(str) return strings.ReplaceAll(str, " ", "") } func (s Service) UUIDFunc() string { if len(s.UUID) == 4 { return "New16BitUUID(0x" + s.UUID + ")" } uuid, err := bluetooth.ParseUUID(strings.ToLower(s.UUID)) if err != nil { panic(err) } b := uuid.Bytes() bs := hex.EncodeToString(b[:]) bss := "" for i := 0; i < len(bs); i += 2 { bss = "0x" + bs[i:i+2] + "," + bss } return "NewUUID([16]byte{" + bss + "})" } func dedupServices(services []Service) []Service { // Group services by name. byName := make(map[string][]Service) for _, svc := range services { byName[svc.Name] = append(byName[svc.Name], svc) } var newServices []Service // Find duplicate services and rename them. for name, svcs := range byName { for i, svc := range svcs { if len(svcs) > 1 { svc.Name = fmt.Sprintf("%s %d", name, i+1) } newServices = append(newServices, svc) } } return newServices } func main() { jsonFile, err := os.Open("bluetooth-numbers-database/v1/service_uuids.json") if err != nil { fmt.Println(err) } defer jsonFile.Close() data, _ := ioutil.ReadAll(jsonFile) var services []Service json.Unmarshal(data, &services) services = dedupServices(services) f, err := os.Create("service_uuids.go") if err != nil { fmt.Println(err) return } defer f.Close() packageTemplate := template.Must(template.New("").Parse(tmpl)) packageTemplate.Execute(f, struct { Timestamp time.Time Services []Service }{ Timestamp: time.Now(), Services: services, }) } var tmpl = `// Code generated by bin/gen-service-uuids; DO NOT EDIT. // This file was generated on {{.Timestamp}} using the list of standard service UUIDs from // https://github.com/NordicSemiconductor/bluetooth-numbers-database/blob/master/v1/service_uuids.json // package bluetooth var ( {{ range .Services }} // ServiceUUID{{.VarName}} - {{.Name}} ServiceUUID{{.VarName}} = {{.UUIDFunc}} {{ end }} ) `