use std::fmt;
use std::ops::Bound;
#[allow(unused_imports)]
#[cfg(test)]
use proptest::arbitrary::any_with;
#[allow(unused_imports)]
#[cfg(test)]
use proptest::collection::size_range;
#[cfg(test)]
use proptest_derive::Arbitrary;
use super::HexRepr;
use crate::kv::codec::BytesEncoder;
use crate::kv::codec::{self};
use crate::proto::kvrpcpb;
use crate::proto::kvrpcpb::KvPair;
const _PROPTEST_KEY_MAX: usize = 1024 * 2;
#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[cfg_attr(test, derive(Arbitrary))]
#[repr(transparent)]
pub struct Key(
#[cfg_attr(
test,
proptest(strategy = "any_with::<Vec<u8>>((size_range(_PROPTEST_KEY_MAX), ()))")
)]
pub(crate) Vec<u8>,
);
impl AsRef<Key> for kvrpcpb::Mutation {
fn as_ref(&self) -> &Key {
self.key.as_ref()
}
}
pub struct KvPairTTL(pub KvPair, pub u64);
impl AsRef<Key> for KvPairTTL {
fn as_ref(&self) -> &Key {
self.0.key.as_ref()
}
}
impl From<KvPairTTL> for (KvPair, u64) {
fn from(value: KvPairTTL) -> Self {
(value.0, value.1)
}
}
impl Key {
/// The empty key.
pub const EMPTY: Self = Key(Vec::new());
/// Return whether the key is empty.
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
/// Return whether the last byte of key is 0.
#[inline]
pub(super) fn zero_terminated(&self) -> bool {
self.0.last().map(|i| *i == 0).unwrap_or(false)
}
/// Push a zero to the end of the key.
///
/// Extending a zero makes the new key the smallest key that is greater than than the original one.
#[inline]
pub(crate) fn next_key(mut self) -> Self {
self.0.push(0);
self
}
/// Convert the key to a lower bound. The key is treated as inclusive.
#[inline]
pub(super) fn into_lower_bound(mut self) -> Bound<Key> {
if self.zero_terminated() {
self.0.pop().unwrap();
Bound::Excluded(self)
} else {
Bound::Included(self)
}
}
/// Convert the key to an upper bound. The key is treated as exclusive.
#[inline]
pub(super) fn into_upper_bound(mut self) -> Bound<Key> {
if self.zero_terminated() {
self.0.pop().unwrap();
Bound::Included(self)
} else {
Bound::Excluded(self)
}
}
/// Return the MVCC-encoded representation of the key.
#[inline]
#[must_use]
pub fn to_encoded(&self) -> Key {
let len = codec::max_encoded_bytes_size(self.0.len());
let mut encoded = Vec::with_capacity(len);
encoded.encode_bytes(&self.0, false).unwrap();
Key(encoded)
}
pub fn len(&self) -> usize {
self.0.len()
}
}
impl From<Vec<u8>> for Key {
fn from(v: Vec<u8>) -> Self {
Key(v)
}
}
impl From<String> for Key {
fn from(v: String) -> Key {
Key(v.into_bytes())
}
}
impl From<Key> for Vec<u8> {
fn from(key: Key) -> Self {
key.0
}
}
impl<'a> From<&'a Key> for &'a [u8] {
fn from(key: &'a Key) -> Self {
&key.0
}
}
impl<'a> From<&'a Vec<u8>> for &'a Key {
fn from(key: &'a Vec<u8>) -> Self {
unsafe { &*(key as *const Vec<u8> as *const Key) }
}
}
impl AsRef<Key> for Key {
fn as_ref(&self) -> &Key {
self
}
}
impl AsRef<Key> for Vec<u8> {
fn as_ref(&self) -> &Key {
unsafe { &*(self as *const Vec<u8> as *const Key) }
}
}
impl fmt::Debug for Key {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Key({})", HexRepr(&self.0))
}
}