diff options
| author | Dax <[email protected]> | 2025-07-13 17:22:11 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-13 17:22:11 -0400 |
| commit | 90d6c4ab41bb097d7db354109e3616ff16778f0b (patch) | |
| tree | 303861ce5789f6e0e8e843cb8184dea829b4885d /packages/tui/internal/id | |
| parent | 736396fc70ab05204b886634ffbcd1318d82eca8 (diff) | |
| download | opencode-90d6c4ab41bb097d7db354109e3616ff16778f0b.tar.gz opencode-90d6c4ab41bb097d7db354109e3616ff16778f0b.zip | |
Part data model (#950)
Diffstat (limited to 'packages/tui/internal/id')
| -rw-r--r-- | packages/tui/internal/id/id.go | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/packages/tui/internal/id/id.go b/packages/tui/internal/id/id.go new file mode 100644 index 000000000..0490b8f20 --- /dev/null +++ b/packages/tui/internal/id/id.go @@ -0,0 +1,96 @@ +package id + +import ( + "crypto/rand" + "encoding/hex" + "fmt" + "strings" + "sync" + "time" +) + +const ( + PrefixSession = "ses" + PrefixMessage = "msg" + PrefixUser = "usr" + PrefixPart = "prt" +) + +const length = 26 + +var ( + lastTimestamp int64 + counter int64 + mu sync.Mutex +) + +type Prefix string + +const ( + Session Prefix = PrefixSession + Message Prefix = PrefixMessage + User Prefix = PrefixUser + Part Prefix = PrefixPart +) + +func ValidatePrefix(id string, prefix Prefix) bool { + return strings.HasPrefix(id, string(prefix)) +} + +func Ascending(prefix Prefix, given ...string) string { + return generateID(prefix, false, given...) +} + +func Descending(prefix Prefix, given ...string) string { + return generateID(prefix, true, given...) +} + +func generateID(prefix Prefix, descending bool, given ...string) string { + if len(given) > 0 && given[0] != "" { + if !strings.HasPrefix(given[0], string(prefix)) { + panic(fmt.Sprintf("ID %s does not start with %s", given[0], string(prefix))) + } + return given[0] + } + + return generateNewID(prefix, descending) +} + +func randomBase62(length int) string { + const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + result := make([]byte, length) + bytes := make([]byte, length) + rand.Read(bytes) + + for i := 0; i < length; i++ { + result[i] = chars[bytes[i]%62] + } + + return string(result) +} + +func generateNewID(prefix Prefix, descending bool) string { + mu.Lock() + defer mu.Unlock() + + currentTimestamp := time.Now().UnixMilli() + + if currentTimestamp != lastTimestamp { + lastTimestamp = currentTimestamp + counter = 0 + } + counter++ + + now := uint64(currentTimestamp)*0x1000 + uint64(counter) + + if descending { + now = ^now + } + + timeBytes := make([]byte, 6) + for i := 0; i < 6; i++ { + timeBytes[i] = byte((now >> (40 - 8*i)) & 0xff) + } + + return string(prefix) + "_" + hex.EncodeToString(timeBytes) + randomBase62(length-12) +}
\ No newline at end of file |
