func WithPrefix() OpOption {
	return func(op *Op) {
		op.key += "%"
	}
}
WithPrefix enables 'Get', 'Delete', or 'Watch' requests to operate
on the keys with matching prefix. For example, 'Get(foo, WithPrefix())'
can return 'foo1', 'foo2', and so on.
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 + "%"
}