96 lines
2.6 KiB
Go
96 lines
2.6 KiB
Go
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
|
|
}
|