tikv_client/kv/
bound_range.rs1use std::borrow::Borrow;
4use std::cmp::Eq;
5use std::cmp::PartialEq;
6use std::ops::Bound;
7use std::ops::Range;
8use std::ops::RangeBounds;
9use std::ops::RangeFrom;
10use std::ops::RangeFull;
11use std::ops::RangeInclusive;
12use std::ops::RangeTo;
13use std::ops::RangeToInclusive;
14
15#[cfg(test)]
16use proptest_derive::Arbitrary;
17
18use super::Key;
19use crate::proto::kvrpcpb;
20
21#[derive(Clone, Debug, Eq, PartialEq)]
68#[cfg_attr(test, derive(Arbitrary))]
69pub struct BoundRange {
70 pub from: Bound<Key>,
71 pub to: Bound<Key>,
72}
73
74impl BoundRange {
75 pub fn new(from: Bound<Key>, to: Bound<Key>) -> BoundRange {
79 BoundRange { from, to }
80 }
81
82 pub fn range_from(from: Key) -> BoundRange {
84 BoundRange {
85 from: Bound::Included(from),
86 to: Bound::Unbounded,
87 }
88 }
89
90 pub fn into_keys(self) -> (Key, Option<Key>) {
137 let start = match self.from {
138 Bound::Included(v) => v,
139 Bound::Excluded(v) => v.next_key(),
140 Bound::Unbounded => Key::EMPTY,
141 };
142 let end = match self.to {
143 Bound::Included(v) => Some(v.next_key()),
144 Bound::Excluded(v) => Some(v),
145 Bound::Unbounded => None,
146 };
147 (start, end)
148 }
149}
150
151impl RangeBounds<Key> for BoundRange {
152 #[allow(clippy::needless_match)]
154 fn start_bound(&self) -> Bound<&Key> {
155 match &self.from {
156 Bound::Included(f) => Bound::Included(f),
157 Bound::Excluded(f) => Bound::Excluded(f),
158 Bound::Unbounded => Bound::Unbounded,
159 }
160 }
161
162 fn end_bound(&self) -> Bound<&Key> {
163 match &self.to {
164 Bound::Included(t) => {
165 if t.is_empty() {
166 Bound::Unbounded
167 } else {
168 Bound::Included(t)
169 }
170 }
171 Bound::Excluded(t) => {
172 if t.is_empty() {
173 Bound::Unbounded
174 } else {
175 Bound::Excluded(t)
176 }
177 }
178 Bound::Unbounded => Bound::Unbounded,
179 }
180 }
181}
182
183impl<T: Into<Key> + Clone> PartialEq<(Bound<T>, Bound<T>)> for BoundRange {
185 fn eq(&self, other: &(Bound<T>, Bound<T>)) -> bool {
186 self.from == convert_to_bound_key(other.0.clone())
187 && self.to == convert_to_bound_key(other.1.clone())
188 }
189}
190
191impl<T: Into<Key>> From<Range<T>> for BoundRange {
192 fn from(other: Range<T>) -> BoundRange {
193 BoundRange::new(
194 Bound::Included(other.start.into()),
195 Bound::Excluded(other.end.into()),
196 )
197 }
198}
199
200impl<T: Into<Key>> From<RangeFrom<T>> for BoundRange {
201 fn from(other: RangeFrom<T>) -> BoundRange {
202 BoundRange::new(Bound::Included(other.start.into()), Bound::Unbounded)
203 }
204}
205
206impl<T: Into<Key>> From<RangeTo<T>> for BoundRange {
207 fn from(other: RangeTo<T>) -> BoundRange {
208 BoundRange::new(Bound::Unbounded, Bound::Excluded(other.end.into()))
209 }
210}
211
212impl<T: Into<Key>> From<RangeInclusive<T>> for BoundRange {
213 fn from(other: RangeInclusive<T>) -> BoundRange {
214 let (start, end) = other.into_inner();
215 BoundRange::new(Bound::Included(start.into()), Bound::Included(end.into()))
216 }
217}
218
219impl<T: Into<Key>> From<RangeToInclusive<T>> for BoundRange {
220 fn from(other: RangeToInclusive<T>) -> BoundRange {
221 BoundRange::new(Bound::Unbounded, Bound::Included(other.end.into()))
222 }
223}
224
225impl From<RangeFull> for BoundRange {
226 fn from(_other: RangeFull) -> BoundRange {
227 BoundRange::new(Bound::Unbounded, Bound::Unbounded)
228 }
229}
230
231impl<T: Into<Key>> From<(T, Option<T>)> for BoundRange {
232 fn from(other: (T, Option<T>)) -> BoundRange {
233 let to = match other.1 {
234 None => Bound::Unbounded,
235 Some(to) => to.into().into_upper_bound(),
236 };
237
238 BoundRange::new(other.0.into().into_lower_bound(), to)
239 }
240}
241
242impl<T: Into<Key>> From<(T, T)> for BoundRange {
243 fn from(other: (T, T)) -> BoundRange {
244 BoundRange::new(
245 other.0.into().into_lower_bound(),
246 other.1.into().into_upper_bound(),
247 )
248 }
249}
250
251impl<T: Into<Key> + Eq> From<(Bound<T>, Bound<T>)> for BoundRange {
252 fn from(bounds: (Bound<T>, Bound<T>)) -> BoundRange {
253 BoundRange::new(
254 convert_to_bound_key(bounds.0),
255 convert_to_bound_key(bounds.1),
256 )
257 }
258}
259
260impl From<BoundRange> for kvrpcpb::KeyRange {
261 fn from(bound_range: BoundRange) -> Self {
262 let (start, end) = bound_range.into_keys();
263 let mut range = kvrpcpb::KeyRange::default();
264 range.start_key = start.into();
265 range.end_key = end.unwrap_or_default().into();
266 range
267 }
268}
269
270impl From<kvrpcpb::KeyRange> for BoundRange {
271 fn from(range: kvrpcpb::KeyRange) -> Self {
272 let start_key = Key::from(range.start_key);
273 let end_key = Key::from(range.end_key);
274 BoundRange::new(start_key.into_lower_bound(), end_key.into_upper_bound())
275 }
276}
277
278pub trait IntoOwnedRange {
303 fn into_owned(self) -> BoundRange;
305}
306
307impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> IntoOwnedRange for Range<&U> {
308 fn into_owned(self) -> BoundRange {
309 From::from(Range {
310 start: self.start.to_owned(),
311 end: self.end.to_owned(),
312 })
313 }
314}
315
316impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> IntoOwnedRange for RangeFrom<&U> {
317 fn into_owned(self) -> BoundRange {
318 From::from(RangeFrom {
319 start: self.start.to_owned(),
320 })
321 }
322}
323
324impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> IntoOwnedRange for RangeTo<&U> {
325 fn into_owned(self) -> BoundRange {
326 From::from(RangeTo {
327 end: self.end.to_owned(),
328 })
329 }
330}
331
332impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> IntoOwnedRange
333 for RangeInclusive<&U>
334{
335 fn into_owned(self) -> BoundRange {
336 let (from, to) = self.into_inner();
337 From::from(RangeInclusive::new(from.to_owned(), to.to_owned()))
338 }
339}
340
341impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> IntoOwnedRange
342 for RangeToInclusive<&U>
343{
344 fn into_owned(self) -> BoundRange {
345 From::from(RangeToInclusive {
346 end: self.end.to_owned(),
347 })
348 }
349}
350
351impl IntoOwnedRange for RangeFull {
352 fn into_owned(self) -> BoundRange {
353 From::from(self)
354 }
355}
356
357impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> IntoOwnedRange for (&U, Option<&U>) {
358 fn into_owned(self) -> BoundRange {
359 From::from((self.0.to_owned(), self.1.map(|u| u.to_owned())))
360 }
361}
362
363impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> IntoOwnedRange for (&U, &U) {
364 fn into_owned(self) -> BoundRange {
365 From::from((self.0.to_owned(), self.1.to_owned()))
366 }
367}
368
369fn convert_to_bound_key<K: Into<Key>>(b: Bound<K>) -> Bound<Key> {
370 match b {
371 Bound::Included(k) => Bound::Included(k.into()),
372 Bound::Excluded(k) => Bound::Excluded(k.into()),
373 Bound::Unbounded => Bound::Unbounded,
374 }
375}