1mod compact;
2mod delete;
3mod put;
4mod range;
5mod txn;
6
7pub use compact::{CompactRequest, CompactResponse};
8pub use delete::{DeleteRequest, DeleteResponse};
9pub use put::{PutRequest, PutResponse};
10pub use range::{RangeRequest, RangeResponse};
11pub use txn::{TxnCmp, TxnOp, TxnOpResponse, TxnRequest, TxnResponse};
12
13use std::{future::Future, ops::Range};
14
15use crate::Result;
16use crate::lease::LeaseId;
17use crate::proto::mvccpb;
18
19pub trait KeyValueOp {
20 fn put<R>(&self, req: R) -> impl Future<Output = Result<PutResponse>>
21 where
22 R: Into<PutRequest>;
23
24 fn get<R>(&self, req: R) -> impl Future<Output = Result<RangeResponse>>
25 where
26 R: Into<RangeRequest>;
27 fn get_all(&self) -> impl Future<Output = Result<RangeResponse>>;
28 fn get_by_prefix<K>(&self, p: K) -> impl Future<Output = Result<RangeResponse>>
29 where
30 K: Into<Vec<u8>>;
31 fn get_range<F, E>(&self, from: F, end: E) -> impl Future<Output = Result<RangeResponse>>
32 where
33 F: Into<Vec<u8>>,
34 E: Into<Vec<u8>>;
35
36 fn delete<R>(&self, req: R) -> impl Future<Output = Result<DeleteResponse>>
37 where
38 R: Into<DeleteRequest>;
39 fn delete_all(&self) -> impl Future<Output = Result<DeleteResponse>>;
40 fn delete_by_prefix<K>(&self, p: K) -> impl Future<Output = Result<DeleteResponse>>
41 where
42 K: Into<Vec<u8>>;
43 fn delete_range<F, E>(&self, from: F, end: E) -> impl Future<Output = Result<DeleteResponse>>
44 where
45 F: Into<Vec<u8>>,
46 E: Into<Vec<u8>>;
47
48 fn txn<R>(&self, req: R) -> impl Future<Output = Result<TxnResponse>>
49 where
50 R: Into<TxnRequest>;
51
52 fn compact<R>(&self, req: R) -> impl Future<Output = Result<CompactResponse>>
53 where
54 R: Into<CompactRequest>;
55}
56
57#[derive(Clone, PartialEq, Default, Debug)]
59pub struct KeyValue {
60 pub key: Vec<u8>,
61 pub value: Vec<u8>,
62 pub create_revision: i64,
63 pub mod_revision: i64,
64 pub version: i64,
65 pub lease: LeaseId,
66}
67
68impl KeyValue {
69 pub fn key_str(&self) -> &str {
72 std::str::from_utf8(&self.key).expect("convert bytes to string")
73 }
74
75 pub fn value_str(&self) -> &str {
78 std::str::from_utf8(&self.value).expect("convert bytes to string")
79 }
80}
81
82impl From<mvccpb::KeyValue> for KeyValue {
83 fn from(proto: mvccpb::KeyValue) -> Self {
84 Self {
85 key: proto.key,
86 value: proto.value,
87 create_revision: proto.create_revision,
88 mod_revision: proto.mod_revision,
89 version: proto.version,
90 lease: proto.lease,
91 }
92 }
93}
94
95#[derive(Clone, Hash, PartialEq, Eq)]
97pub struct KeyRange {
98 pub key: Vec<u8>,
99 pub range_end: Vec<u8>,
100}
101
102impl KeyRange {
103 pub fn range<K, R>(key: K, range_end: R) -> Self
105 where
106 K: Into<Vec<u8>>,
107 R: Into<Vec<u8>>,
108 {
109 Self {
110 key: key.into(),
111 range_end: range_end.into(),
112 }
113 }
114
115 pub fn key<K>(key: K) -> Self
117 where
118 K: Into<Vec<u8>>,
119 {
120 Self {
121 key: key.into(),
122 range_end: vec![],
123 }
124 }
125
126 pub fn all() -> Self {
128 Self {
129 key: vec![0],
130 range_end: vec![0],
131 }
132 }
133
134 pub fn prefix<K>(prefix: K) -> Self
136 where
137 K: Into<Vec<u8>>,
138 {
139 let key = prefix.into();
140 if key.is_empty() {
141 return KeyRange::all();
144 }
145
146 let range_end = {
147 let mut end = key.clone();
148
149 for i in (0..end.len()).rev() {
150 if end[i] < 0xff {
151 end[i] += 1;
152 end.truncate(i + 1);
153 break;
154 }
155 }
156 end
157 };
158 Self { key, range_end }
159 }
160}
161
162impl<T> From<Range<T>> for KeyRange
163where
164 T: Into<Vec<u8>>,
165{
166 fn from(range: Range<T>) -> Self {
167 Self::range(range.start, range.end)
168 }
169}
170
171impl From<&str> for KeyRange {
172 fn from(k: &str) -> Self {
173 Self::key(k)
174 }
175}
176
177impl From<String> for KeyRange {
178 fn from(k: String) -> Self {
179 Self::key(k)
180 }
181}