Introduce ToOwnedRange to make handling ranges a bit nicer

Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
Nick Cameron 2019-06-26 14:58:57 +12:00
parent 426d596709
commit 0ed7c8afe3
6 changed files with 55 additions and 12 deletions

View File

@ -6,7 +6,7 @@
mod common;
use crate::common::parse_args;
use tikv_client::{raw::Client, Config, Key, KvPair, Result, Value};
use tikv_client::{raw::Client, Config, Key, KvPair, Result, ToOwnedRange, Value};
const KEY: &str = "TiKV";
const VALUE: &str = "Rust";
@ -89,7 +89,7 @@ async fn main() -> Result<()> {
let end = "k2";
let pairs = client
.with_key_only(true)
.scan(start.to_owned()..=end.to_owned(), 10)
.scan((start..=end).to_owned(), 10)
.await
.expect("Could not scan");

View File

@ -3,6 +3,7 @@
use super::Key;
#[cfg(test)]
use proptest_derive::Arbitrary;
use std::borrow::Borrow;
use std::cmp::{Eq, PartialEq};
use std::convert::TryFrom;
use std::ops::{Bound, Range, RangeFrom, RangeInclusive};
@ -75,17 +76,17 @@ impl BoundRange {
/// The **end** of a scan is exclusive, unless appended with an '\0', then it is inclusive.
///
/// ```rust
/// use tikv_client::{BoundRange, Key};
/// use tikv_client::{BoundRange, Key, ToOwnedRange};
/// // Exclusive
/// let range = "a".to_owned().."z".to_owned();
/// let range = "a".."z";
/// assert_eq!(
/// BoundRange::from(range).into_keys(),
/// BoundRange::from(range.to_owned()).into_keys(),
/// (Key::from("a".to_owned()), Some(Key::from("z".to_owned()))),
/// );
/// // Inclusive
/// let range = "a".to_owned()..="z".to_owned();
/// let range = "a"..="z";
/// assert_eq!(
/// BoundRange::from(range).into_keys(),
/// BoundRange::from(range.to_owned()).into_keys(),
/// (Key::from("a".to_owned()), Some(Key::from("z\0".to_owned()))),
/// );
/// // Open
@ -181,6 +182,48 @@ impl<T: Into<Key> + Eq> TryFrom<(Bound<T>, Bound<T>)> for BoundRange {
}
}
/// A convenience trait for converting ranges of borrowed types into a `BoundRange`.
pub trait ToOwnedRange {
/// Transform a borrowed range of some form into an owned `BoundRange`.
fn to_owned(self) -> BoundRange;
}
impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> ToOwnedRange for Range<&U> {
fn to_owned(self) -> BoundRange {
From::from(Range {
start: self.start.to_owned(),
end: self.end.to_owned(),
})
}
}
impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> ToOwnedRange for RangeFrom<&U> {
fn to_owned(self) -> BoundRange {
From::from(RangeFrom {
start: self.start.to_owned(),
})
}
}
impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> ToOwnedRange for RangeInclusive<&U> {
fn to_owned(self) -> BoundRange {
let (from, to) = self.into_inner();
From::from(RangeInclusive::new(from.to_owned(), to.to_owned()))
}
}
impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> ToOwnedRange for (&U, Option<&U>) {
fn to_owned(self) -> BoundRange {
From::from((self.0.to_owned(), self.1.map(|u| u.to_owned())))
}
}
impl<T: Into<Key> + Borrow<U>, U: ToOwned<Owned = T> + ?Sized> ToOwnedRange for (&U, &U) {
fn to_owned(self) -> BoundRange {
From::from((self.0.to_owned(), self.1.to_owned()))
}
}
fn convert_to_bound_key<K: Into<Key>>(b: Bound<K>) -> Bound<Key> {
match b {
Bound::Included(k) => Bound::Included(k.into()),

View File

@ -6,7 +6,7 @@ use proptest::{arbitrary::any_with, collection::size_range};
#[cfg(test)]
use proptest_derive::Arbitrary;
use std::ops::Bound;
use std::{fmt, str, u8};
use std::{fmt, u8};
/// The key part of a key/value pair.
///

View File

@ -6,7 +6,7 @@ mod key;
mod kvpair;
mod value;
pub use bound_range::BoundRange;
pub use bound_range::{BoundRange, ToOwnedRange};
pub use key::Key;
pub use kvpair::KvPair;
pub use value::Value;

View File

@ -100,4 +100,4 @@ pub use crate::errors::ErrorKind;
#[doc(inline)]
pub use crate::errors::Result;
#[doc(inline)]
pub use crate::kv::{BoundRange, Key, KvPair, Value};
pub use crate::kv::{BoundRange, Key, KvPair, ToOwnedRange, Value};

View File

@ -157,12 +157,12 @@ impl Client {
///
/// ```rust,no_run
/// # #![feature(async_await)]
/// # use tikv_client::{Config, raw::Client};
/// # use tikv_client::{Config, raw::Client, ToOwnedRange};
/// # use futures::prelude::*;
/// # futures::executor::block_on(async {
/// let connect = Client::connect(Config::default());
/// let client = connect.await.unwrap();
/// let scan_request = client.with_key_only(true).scan("TiKV".to_owned()..="TiDB".to_owned(), 2);
/// let scan_request = client.with_key_only(true).scan(("TiKV"..="TiDB").to_owned(), 2);
/// # });
/// ```
pub fn with_key_only(&self, key_only: bool) -> Client {