package uuid import "core:crypto" import "core:io" import "core:mem" UUID_SIZE :: 16 UUID :: distinct [UUID_SIZE]byte generate :: proc() -> (u: UUID) #no_bounds_check { crypto.rand_bytes(u[:]) u[6] = (u[6] & 0x0f) | (4 << 4) u[8] = (u[8] & (0xff >> 2) | (0x02 << 6)) return u } to_string :: proc(dst: []byte, u: UUID) #no_bounds_check { u := u assert(len(dst) >= 36, "dst not big enough for UUID") hex(dst[0:8], u[0:4]) dst[8] = '-' hex(dst[9:13], u[4:6]) dst[13] = '-' hex(dst[14:18], u[6:8]) dst[18] = '-' hex(dst[19:23], u[8:10]) dst[23] = '-' hex(dst[24:], u[10:]) } clone_to_string :: proc( u: UUID, allocator := context.allocator, ) -> ( str: string, err: mem.Allocator_Error, ) { buf := make([]byte, 36, allocator) or_return to_string(buf, u) str = string(buf) delete(buf) return } write :: proc(dst: io.Writer, u: UUID, n_written: ^int = nil) -> (int, io.Error) { buf: [36]byte to_string(buf[:], u) return io.write(dst, buf[:], n_written) } @(private) HEXTABLE := [16]byte { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', } @(private) hex :: proc(dst, src: []byte) #no_bounds_check { i := 0 for v in src { dst[i] = HEXTABLE[v >> 4] dst[i + 1] = HEXTABLE[v & 0x0f] i += 2 } }