Files
dbx/ksuid_parse.go
T
end fa4efb38f7 feat(ksuid): add BinExpr, flexible parsers, and expression helpers
Adds ParseStringKSUIDAny, ParseBinaryKSUIDAny, BinaryKSUID.BinExpr, and
ExprStringKSUIDs for portal-compatible KSUID handling at API boundaries.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 18:26:17 -07:00

70 lines
1.6 KiB
Go

package dbx
import (
"encoding/hex"
"fmt"
"github.com/segmentio/ksuid"
)
// ParseStringKSUIDAny parses a StringKSUID from a string, byte slice, ksuid.KSUID,
// or nil. Accepts base62 string (27 bytes), raw binary (20 bytes), or hex-encoded
// forms (40 or 54 bytes).
func ParseStringKSUIDAny(src any) (StringKSUID, error) {
id, err := parseKSUIDAny(src)
if err != nil {
return NilStringKSUID, err
}
return StringKSUID{KSUID: id}, nil
}
// ParseBinaryKSUIDAny parses a BinaryKSUID from the same accepted forms as
// [ParseStringKSUIDAny].
func ParseBinaryKSUIDAny(src any) (BinaryKSUID, error) {
id, err := parseKSUIDAny(src)
if err != nil {
return NilBinaryKSUID, err
}
return BinaryKSUID{KSUID: id}, nil
}
func parseKSUIDAny(src any) (ksuid.KSUID, error) {
switch v := src.(type) {
case ksuid.KSUID:
return v, nil
case StringKSUID:
return v.KSUID, nil
case BinaryKSUID:
return v.KSUID, nil
case string:
return parseKSUIDBytes([]byte(v))
case []byte:
return parseKSUIDBytes(v)
case nil:
return ksuid.Nil, nil
default:
return ksuid.Nil, fmt.Errorf("cannot parse KSUID from type %T", src)
}
}
func parseKSUIDBytes(src []byte) (ksuid.KSUID, error) {
if len(src) == 40 || len(src) == 54 {
decoded := make([]byte, hex.DecodedLen(len(src)))
if _, err := hex.Decode(decoded, src); err != nil {
return ksuid.Nil, err
}
src = decoded
}
switch len(src) {
case 0:
return ksuid.Nil, nil
case ksuidBinaryLength:
return ksuid.FromBytes(src)
case ksuidStringLength:
return ksuid.Parse(string(src))
default:
return ksuid.Nil, fmt.Errorf("cannot parse KSUID from byte slice of length %d", len(src))
}
}