gcx/backend/services/trading-service/internal/domain/vo/quantity.go

81 lines
1.8 KiB
Go

package vo
import "fmt"
// Quantity is a value object representing a positive integer quantity.
type Quantity struct {
value int
}
// NewQuantity creates a validated Quantity. Value must be positive (> 0).
func NewQuantity(v int) (Quantity, error) {
if v <= 0 {
return Quantity{}, fmt.Errorf("quantity must be positive, got %d", v)
}
return Quantity{value: v}, nil
}
// MustNewQuantity creates a Quantity, panicking on invalid input. Use only in tests.
func MustNewQuantity(v int) Quantity {
q, err := NewQuantity(v)
if err != nil {
panic(err)
}
return q
}
// QuantityFromInt creates a Quantity from an int, allowing zero (for remaining qty tracking).
func QuantityFromInt(v int) Quantity {
if v < 0 {
v = 0
}
return Quantity{value: v}
}
// ZeroQuantity returns a zero quantity.
func ZeroQuantity() Quantity {
return Quantity{value: 0}
}
// Int returns the underlying integer value.
func (q Quantity) Int() int {
return q.value
}
// IsZero returns true if quantity is zero.
func (q Quantity) IsZero() bool {
return q.value == 0
}
// IsPositive returns true if quantity is > 0.
func (q Quantity) IsPositive() bool {
return q.value > 0
}
// Add returns a new Quantity that is the sum of two quantities.
func (q Quantity) Add(other Quantity) Quantity {
return Quantity{value: q.value + other.value}
}
// Subtract returns a new Quantity, clamped to zero if result would be negative.
func (q Quantity) Subtract(other Quantity) Quantity {
result := q.value - other.value
if result < 0 {
result = 0
}
return Quantity{value: result}
}
// Min returns the smaller of two quantities.
func (q Quantity) Min(other Quantity) Quantity {
if q.value < other.value {
return q
}
return other
}
// String returns a human-readable representation.
func (q Quantity) String() string {
return fmt.Sprintf("%d", q.value)
}