Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 55s
cart.sx — cart as an ordered list of (sku variant qty) lines. Pure operations: cart-add (merge-or-append), cart-set-qty (0 removes), cart-remove, with cart-qty/count/skus/empty? accessors. cart-lineo exposes lines relationally via membero. Total 34/34. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
87 lines
2.3 KiB
Plaintext
87 lines
2.3 KiB
Plaintext
;; lib/commerce/cart.sx — cart as an ordered list of line items.
|
|
;;
|
|
;; A cart is a native list of lines; a line is (list sku variant qty).
|
|
;; All operations are pure: they return a new cart, never mutate. Line
|
|
;; order is insertion order (stable) so totals are reproducible.
|
|
;;
|
|
;; cart-lineo is the relational view — because a line *is* a (sku variant qty)
|
|
;; tuple, membero queries the cart directly, forward or backward.
|
|
|
|
(define empty-cart (list))
|
|
|
|
(define make-line (fn (sku variant qty) (list sku variant qty)))
|
|
(define line-sku (fn (l) (nth l 0)))
|
|
(define line-variant (fn (l) (nth l 1)))
|
|
(define line-qty (fn (l) (nth l 2)))
|
|
|
|
(define
|
|
same-line?
|
|
(fn
|
|
(l sku variant)
|
|
(and (= (line-sku l) sku) (= (line-variant l) variant))))
|
|
|
|
(define
|
|
cart-qty
|
|
(fn
|
|
(cart sku variant)
|
|
(let
|
|
((m (filter (fn (l) (same-line? l sku variant)) cart)))
|
|
(if (empty? m) 0 (line-qty (first m))))))
|
|
|
|
(define
|
|
cart-remove
|
|
(fn
|
|
(cart sku variant)
|
|
(filter (fn (l) (not (same-line? l sku variant))) cart)))
|
|
|
|
;; Add qty units; merges into an existing (sku,variant) line in place,
|
|
;; otherwise appends a new line at the end.
|
|
(define
|
|
cart-add
|
|
(fn
|
|
(cart sku variant qty)
|
|
(let
|
|
((existing (cart-qty cart sku variant)))
|
|
(if
|
|
(= existing 0)
|
|
(append cart (list (make-line sku variant qty)))
|
|
(map
|
|
(fn
|
|
(l)
|
|
(if
|
|
(same-line? l sku variant)
|
|
(make-line sku variant (+ existing qty))
|
|
l))
|
|
cart)))))
|
|
|
|
;; Set the absolute quantity; qty <= 0 removes the line.
|
|
(define
|
|
cart-set-qty
|
|
(fn
|
|
(cart sku variant qty)
|
|
(if
|
|
(<= qty 0)
|
|
(cart-remove cart sku variant)
|
|
(if
|
|
(= (cart-qty cart sku variant) 0)
|
|
(append cart (list (make-line sku variant qty)))
|
|
(map
|
|
(fn
|
|
(l)
|
|
(if (same-line? l sku variant) (make-line sku variant qty) l))
|
|
cart)))))
|
|
|
|
(define cart-empty? (fn (cart) (empty? cart)))
|
|
(define cart-lines (fn (cart) cart))
|
|
(define cart-skus (fn (cart) (map line-sku cart)))
|
|
|
|
;; Total number of units across all lines.
|
|
(define
|
|
cart-count
|
|
(fn (cart) (reduce (fn (acc l) (+ acc (line-qty l))) 0 cart)))
|
|
|
|
;; Relational view of cart lines.
|
|
(define
|
|
cart-lineo
|
|
(fn (cart sku variant qty) (membero (list sku variant qty) cart)))
|