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 }