//go: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 Characteristic struct { Name string `json:"name"` Identifier string `json:"identifier"` UUID string `json:"uuid"` Source string `json:"source"` } func (c Characteristic) VarName() string { str := strings.ReplaceAll(c.Name, "Characteristic", "") // 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 (c Characteristic) UUIDFunc() string { if len(c.UUID) == 4 { return "New16BitUUID(0x" + c.UUID + ")" } uuid, err := bluetooth.ParseUUID(strings.ToLower(c.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 dedupCharacteristics(characteristics []Characteristic) []Characteristic { // Group characteristics by name. byName := make(map[string][]Characteristic) for _, c := range characteristics { byName[c.Name] = append(byName[c.Name], c) } var newCharacteristics []Characteristic // Find duplicate characteristics and rename them. for name, cs := range byName { for i, c := range cs { if len(cs) > 1 { c.Name = fmt.Sprintf("%s %d", name, i+1) } newCharacteristics = append(newCharacteristics, c) } } return newCharacteristics } func main() { jsonFile, err := os.Open("bluetooth-numbers-database/v1/characteristic_uuids.json") if err != nil { fmt.Println(err) } defer jsonFile.Close() data, _ := ioutil.ReadAll(jsonFile) var characteristics []Characteristic json.Unmarshal(data, &characteristics) characteristics = dedupCharacteristics(characteristics) f, err := os.Create("characteristic_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 Characteristics []Characteristic }{ Timestamp: time.Now(), Characteristics: characteristics, }) } var tmpl = `// Code generated by bin/gen-characteristic-uuids; DO NOT EDIT. // This file was generated on {{.Timestamp}} using the list of standard characteristics UUIDs from // https://github.com/NordicSemiconductor/bluetooth-numbers-database/blob/master/v1/characteristics_uuids.json // package bluetooth var ( {{ range .Characteristics }} // CharacteristicUUID{{.VarName}} - {{.Name}} CharacteristicUUID{{.VarName}} = {{.UUIDFunc}} {{ end }} ) `