use crate::value::Value;
#[macro_export]
macro_rules! key {
($($val:expr),* $(,)?) => {
$crate::key::Key::new(vec![
$($crate::value::ToValue::to_value(&$val)),*
])
};
}
#[derive(Clone, Debug, PartialEq)]
pub struct Key {
pub(crate) values: Vec<Value>,
}
impl Key {
pub fn new(values: Vec<Value>) -> Self {
Key { values }
}
pub(crate) fn into_values(self) -> Vec<serde_json::Value> {
self.values
.into_iter()
.map(|v| v.into_serde_value())
.collect()
}
}
impl Default for Key {
fn default() -> Self {
Self::new(vec![])
}
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) enum Endpoint {
Closed(Key),
Open(Key),
}
#[derive(Clone, Debug, PartialEq)]
pub struct KeyRange {
pub(crate) start: Endpoint,
pub(crate) end: Endpoint,
}
impl KeyRange {
pub fn closed_open(start: Key, end: Key) -> Self {
KeyRange {
start: Endpoint::Closed(start),
end: Endpoint::Open(end),
}
}
pub fn closed_closed(start: Key, end: Key) -> Self {
KeyRange {
start: Endpoint::Closed(start),
end: Endpoint::Closed(end),
}
}
pub fn open_closed(start: Key, end: Key) -> Self {
KeyRange {
start: Endpoint::Open(start),
end: Endpoint::Closed(end),
}
}
pub fn open_open(start: Key, end: Key) -> Self {
KeyRange {
start: Endpoint::Open(start),
end: Endpoint::Open(end),
}
}
#[allow(dead_code)]
pub(crate) fn into_proto(self) -> crate::model::KeyRange {
let mut proto = crate::model::KeyRange::new();
proto = match self.start {
Endpoint::Closed(start) => proto.set_start_closed(start.into_values()),
Endpoint::Open(start) => proto.set_start_open(start.into_values()),
};
match self.end {
Endpoint::Closed(end) => proto.set_end_closed(end.into_values()),
Endpoint::Open(end) => proto.set_end_open(end.into_values()),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct KeySet {
pub(crate) keys: Vec<Key>,
pub(crate) ranges: Vec<KeyRange>,
pub(crate) all: bool,
}
impl KeySet {
pub fn builder() -> KeySetBuilder {
KeySetBuilder::new()
}
pub fn all() -> Self {
KeySet {
keys: vec![],
ranges: vec![],
all: true,
}
}
#[allow(dead_code)]
pub(crate) fn into_proto(self) -> crate::model::KeySet {
let mut proto = crate::model::KeySet::new();
if self.all {
proto = proto.set_all(true);
}
let keys_proto: Vec<Vec<serde_json::Value>> =
self.keys.into_iter().map(|k| k.into_values()).collect();
if !keys_proto.is_empty() {
proto = proto.set_keys(keys_proto);
}
let ranges_proto: Vec<crate::model::KeyRange> =
self.ranges.into_iter().map(|r| r.into_proto()).collect();
if !ranges_proto.is_empty() {
proto = proto.set_ranges(ranges_proto);
}
proto
}
}
#[derive(Clone, Debug)]
pub struct KeySetBuilder {
keys: Vec<Key>,
ranges: Vec<KeyRange>,
}
impl KeySetBuilder {
pub fn new() -> Self {
KeySetBuilder {
keys: vec![],
ranges: vec![],
}
}
pub fn add_key(mut self, key: Key) -> Self {
self.keys.push(key);
self
}
pub fn add_range(mut self, range: KeyRange) -> Self {
self.ranges.push(range);
self
}
pub fn build(self) -> KeySet {
KeySet {
keys: self.keys,
ranges: self.ranges,
all: false,
}
}
}
impl Default for KeySetBuilder {
fn default() -> Self {
Self::new()
}
}
impl Default for KeySet {
fn default() -> Self {
KeySet::builder().build()
}
}
impl From<Key> for KeySet {
fn from(key: Key) -> Self {
KeySet::builder().add_key(key).build()
}
}
impl From<KeyRange> for KeySet {
fn from(range: KeyRange) -> Self {
KeySet::builder().add_range(range).build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn auto_traits() {
static_assertions::assert_impl_all!(Endpoint: Send, Sync, Clone, std::fmt::Debug);
static_assertions::assert_impl_all!(Key: Send, Sync, Clone, std::fmt::Debug);
static_assertions::assert_impl_all!(KeyRange: Send, Sync, Clone, std::fmt::Debug);
static_assertions::assert_impl_all!(KeySet: Send, Sync, Clone, std::fmt::Debug);
static_assertions::assert_impl_all!(KeySetBuilder: Send, Sync, Clone, std::fmt::Debug);
}
#[test]
fn key_builder() {
let key = key![1_i64, "test"];
assert_eq!(key.values.len(), 2);
}
#[test]
fn key_default() {
let key = Key::default();
assert_eq!(key.values.len(), 0);
}
#[test]
fn key_into_values() {
let key = key![1_i64];
let values = key.into_values();
assert_eq!(values.len(), 1);
assert_eq!(values[0], serde_json::json!("1"));
}
#[test]
fn keyrange_factories() {
let start = key![1_i64];
let end = key![10_i64];
let r1 = KeyRange::closed_open(start.clone(), end.clone());
assert_eq!(r1.start, Endpoint::Closed(start.clone()));
assert_eq!(r1.end, Endpoint::Open(end.clone()));
let r2 = KeyRange::closed_closed(start.clone(), end.clone());
assert_eq!(r2.start, Endpoint::Closed(start.clone()));
assert_eq!(r2.end, Endpoint::Closed(end.clone()));
let r3 = KeyRange::open_closed(start.clone(), end.clone());
assert_eq!(r3.start, Endpoint::Open(start.clone()));
assert_eq!(r3.end, Endpoint::Closed(end.clone()));
let r4 = KeyRange::open_open(start.clone(), end.clone());
assert_eq!(r4.start, Endpoint::Open(start.clone()));
assert_eq!(r4.end, Endpoint::Open(end.clone()));
}
#[test]
fn keyrange_into_proto() {
let r1 = KeyRange::closed_open(key![1_i64], key![10_i64]);
let proto1 = r1.into_proto();
assert_eq!(proto1.start_closed().unwrap().len(), 1);
assert_eq!(proto1.end_open().unwrap().len(), 1);
let r2 = KeyRange::open_closed(key![1_i64], key![10_i64]);
let proto2 = r2.into_proto();
assert_eq!(proto2.start_open().unwrap().len(), 1);
assert_eq!(proto2.end_closed().unwrap().len(), 1);
}
#[test]
fn keyset_builder() {
let key = key![1_i64];
let range = KeyRange::closed_open(key![2_i64], key![5_i64]);
let keyset = KeySet::builder().add_key(key).add_range(range).build();
assert_eq!(keyset.keys.len(), 1);
assert_eq!(keyset.ranges.len(), 1);
assert!(!keyset.all);
}
#[test]
fn keyset_builder_default() {
let builder = KeySetBuilder::default();
let keyset = builder.build();
assert_eq!(keyset.keys.len(), 0);
assert_eq!(keyset.ranges.len(), 0);
}
#[test]
fn keyset_default() {
let keyset = KeySet::default();
assert_eq!(keyset.keys.len(), 0);
assert_eq!(keyset.ranges.len(), 0);
assert!(!keyset.all);
}
#[test]
fn keyset_from_key() {
let keyset: KeySet = key![1_i64].into();
assert_eq!(keyset.keys.len(), 1);
assert_eq!(keyset.ranges.len(), 0);
}
#[test]
fn keyset_from_keyrange() {
let range = KeyRange::closed_open(key![2_i64], key![5_i64]);
let keyset: KeySet = range.into();
assert_eq!(keyset.keys.len(), 0);
assert_eq!(keyset.ranges.len(), 1);
}
#[test]
fn keyset_into_proto() {
let keyset = KeySet::all();
let proto = keyset.into_proto();
assert!(proto.all);
let keyset2 = KeySet::builder()
.add_key(key![1_i64])
.add_range(KeyRange::closed_open(key![2_i64], key![5_i64]))
.build();
let proto2 = keyset2.into_proto();
assert_eq!(proto2.keys.len(), 1);
assert_eq!(proto2.ranges.len(), 1);
}
}