package cart import ( "encoding/json" "fmt" "git.k6n.net/mats/platform/uid" ) // cart_id.go // // Breaking change: // Unified cart identifier as a raw 64-bit unsigned integer (type CartId uint64). // External textual representation: base62 (0-9 A-Z a-z), shortest possible // encoding for 64 bits (max 11 characters, since 62^11 > 2^64). // // Rationale: // - Replaces legacy fixed [16]byte padded string and transitional CartID wrapper. // - Provides compact, URL/cookie-friendly identifiers. // - O(1) hashing and minimal memory footprint. // - 64 bits of crypto randomness => negligible collision probability at realistic scale. // // Public API: // type CartId uint64 // func NewCartId() (CartId, error) // func MustNewCartId() CartId // func ParseCartId(string) (CartId, bool) // func MustParseCartId(string) CartId // (CartId).String() string // (CartId).MarshalJSON() / UnmarshalJSON() // // NOTE: // All legacy helpers (UpgradeLegacyCartId, Fallback hashing, Canonicalize variants, // CartIDToLegacy, LegacyToCartID) have been removed as part of the breaking change. // // --------------------------------------------------------------------------- // CartId is a 64-bit cart identifier with a compact base62 string form, // backed by the shared platform/uid package. type CartId uid.ID // String returns the canonical base62 encoding. func (id CartId) String() string { return uid.ID(id).String() } // MarshalJSON encodes the cart id as a JSON string. func (id CartId) MarshalJSON() ([]byte, error) { return json.Marshal(uid.ID(id).String()) } // UnmarshalJSON decodes a cart id from a JSON string containing base62 text. func (id *CartId) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } parsed, ok := ParseCartId(s) if !ok { return fmt.Errorf("invalid cart id: %q", s) } *id = parsed return nil } // NewCartId generates a new cryptographically random non-zero 64-bit id. func NewCartId() (CartId, error) { id, err := uid.New() if err != nil { return 0, fmt.Errorf("NewCartId: %w", err) } return CartId(id), nil } // MustNewCartId panics if generation fails. func MustNewCartId() CartId { id, err := NewCartId() if err != nil { panic(err) } return id } // ParseCartId parses a base62 string into a CartId. func ParseCartId(s string) (CartId, bool) { id, ok := uid.Parse(s) return CartId(id), ok } // MustParseCartId panics on invalid base62 input. func MustParseCartId(s string) CartId { id, ok := ParseCartId(s) if !ok { panic(fmt.Sprintf("invalid cart id: %q", s)) } return id }