func WithPrevKV() OpOption {
	return func(op *Op) {
		op.prevKV = true
	}
}
WithPrevKV gets the previous key-value pair before the event happens. If the previous KV is already compacted,
nothing will be returned.
package clientv3
import pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
type opType int
const (
	tRange opType = iota + 1
	tPut
	tDeleteRange
	tTxn
)
var (
	noPrefixEnd = []byte{0}
)
type Op struct {
	t           opType
	key         string
	boundingKey string
	limit     int64
	countOnly bool
	rev int64
	prevKV bool
	val     []byte
	leaseID LeaseID
	cmps    []Cmp
	thenOps []Op
	elseOps []Op
}
func (op Op) IsTxn() bool              { return op.t == tTxn }
func (op Op) Txn() ([]Cmp, []Op, []Op) { return op.cmps, op.thenOps, op.elseOps }
func (op Op) Rev() int64 { return op.rev }
func (op Op) IsPut() bool { return op.t == tPut }
func (op Op) IsGet() bool { return op.t == tRange }
func (op Op) IsDelete() bool { return op.t == tDeleteRange }
func (op Op) IsCountOnly() bool { return op.countOnly == true }
func (op Op) ValueBytes() []byte { return op.val }
func (op *Op) WithValueBytes(v []byte) { op.val = v }
func (op Op) toRangeRequest() *pb.RangeRequest {
	if op.t != tRange {
		panic("op.t != tRange")
	}
	r := &pb.RangeRequest{
		Key:       []byte(op.key),
		RangeEnd:  []byte(op.boundingKey),
		Limit:     op.limit,
		Revision:  op.rev,
		CountOnly: op.countOnly,
	}
	return r
}
func OpGet(key string, opts ...OpOption) Op {
	ret := Op{t: tRange, key: key}
	ret.applyOpts(opts)
	return ret
}
func OpDelete(key string, opts ...OpOption) Op {
	ret := Op{t: tDeleteRange, key: key}
	ret.applyOpts(opts)
	switch {
	case ret.leaseID != 0:
		panic("unexpected lease in delete")
	case ret.limit != 0:
		panic("unexpected limit in delete")
	case ret.rev != 0:
		panic("unexpected revision in delete")
	case ret.countOnly:
		panic("unexpected countOnly in delete")
	}
	return ret
}
func OpPut(key, val string, opts ...OpOption) Op {
	ret := Op{t: tPut, key: key, val: []byte(val)}
	ret.applyOpts(opts)
	switch {
	case len(ret.key) > 0 && ret.key[len(ret.key)-1] == '%':
		panic("unexpected range in put")
	case ret.limit != 0:
		panic("unexpected limit in put")
	case ret.rev != 0:
		panic("unexpected revision in put")
	case ret.countOnly:
		panic("unexpected countOnly in put")
	}
	return ret
}
func (op *Op) applyOpts(opts []OpOption) {
	for _, opt := range opts {
		opt(op)
	}
}
type OpOption func(*Op)
func WithLease(leaseID LeaseID) OpOption {
	return func(op *Op) { op.leaseID = leaseID }
}
func WithLimit(n int64) OpOption { return func(op *Op) { op.limit = n } }
func WithRev(rev int64) OpOption { return func(op *Op) { op.rev = rev } }
func GetPrefixRangeEnd(prefix string) string {
	return prefix + "%"
}
func WithPrefix() OpOption {
	return func(op *Op) {
		op.key += "%"
	}
}
func WithRange(endKey string) OpOption {
	return func(op *Op) { op.boundingKey = endKey }
}
func WithSerializable() OpOption {
	return func(op *Op) {}
}
func WithCountOnly() OpOption {
	return func(op *Op) { op.countOnly = true }
}