feat: add command domain invariants
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidRevision = errors.New("command revision must be nonzero")
|
||||
ErrRevisionOverflow = errors.New("command revision overflow")
|
||||
ErrStaleRevision = errors.New("stale command revision")
|
||||
ErrFutureRevision = errors.New("unexpected future command revision")
|
||||
)
|
||||
|
||||
type CommandRevision uint64
|
||||
|
||||
const InitialCommandRevision CommandRevision = 1
|
||||
|
||||
type RevisionRelation uint8
|
||||
|
||||
const (
|
||||
RevisionInvalid RevisionRelation = iota
|
||||
RevisionStale
|
||||
RevisionCurrent
|
||||
RevisionFuture
|
||||
)
|
||||
|
||||
func CompareRevision(current, incoming CommandRevision) RevisionRelation {
|
||||
if current == 0 || incoming == 0 {
|
||||
return RevisionInvalid
|
||||
}
|
||||
if incoming < current {
|
||||
return RevisionStale
|
||||
}
|
||||
if incoming > current {
|
||||
return RevisionFuture
|
||||
}
|
||||
return RevisionCurrent
|
||||
}
|
||||
|
||||
func ValidateCurrentRevision(current, incoming CommandRevision) error {
|
||||
switch CompareRevision(current, incoming) {
|
||||
case RevisionCurrent:
|
||||
return nil
|
||||
case RevisionStale:
|
||||
return ErrStaleRevision
|
||||
case RevisionFuture:
|
||||
return ErrFutureRevision
|
||||
default:
|
||||
return ErrInvalidRevision
|
||||
}
|
||||
}
|
||||
|
||||
// NextRevision durably orders a new cancel or signal intent.
|
||||
func NextRevision(current CommandRevision) (CommandRevision, error) {
|
||||
if current == 0 {
|
||||
return 0, ErrInvalidRevision
|
||||
}
|
||||
if current == math.MaxUint64 {
|
||||
return 0, ErrRevisionOverflow
|
||||
}
|
||||
return current + 1, nil
|
||||
}
|
||||
Reference in New Issue
Block a user