diff --git a/Cargo.lock b/Cargo.lock index 51af54389..e901646b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3832,6 +3832,7 @@ dependencies = [ "strum", "strum_macros", "thiserror", + "utils", "workspace-hack", ] diff --git a/crates/xlineapi/Cargo.toml b/crates/xlineapi/Cargo.toml index 8bdf9dbad..b40a1994a 100644 --- a/crates/xlineapi/Cargo.toml +++ b/crates/xlineapi/Cargo.toml @@ -19,6 +19,7 @@ prost = "0.12.3" serde = { version = "1.0.137", features = ["derive"] } thiserror = "1.0.37" tonic = { version = "0.4.1", package = "madsim-tonic" } +utils = { path = "../utils" } workspace-hack = { version = "0.1", path = "../../workspace-hack" } [build-dependencies] diff --git a/crates/xlineapi/src/interval.rs b/crates/xlineapi/src/interval.rs new file mode 100644 index 000000000..e34f173da --- /dev/null +++ b/crates/xlineapi/src/interval.rs @@ -0,0 +1,76 @@ +use std::cmp; + +use utils::interval_map::Interval; + +use crate::command::KeyRange; + +impl From for Interval { + fn from(range: KeyRange) -> Self { + let start = range.range_start().to_vec(); + let end = match range.range_end() { + &[] => { + let mut end = start.clone(); + end.push(0); + BytesAffine::Bytes(end) + } + &[0] => BytesAffine::Unbounded, + bytes => BytesAffine::Bytes(bytes.to_vec()), + }; + Interval::new(BytesAffine::Bytes(start), end) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum BytesAffine { + /// Bytes + Bytes(Vec), + /// Unbounded + Unbounded, +} + +impl BytesAffine { + pub fn new_key(bytes: impl Into>) -> Self { + Self::Bytes(bytes.into()) + } + + pub fn new_unbounded() -> Self { + Self::Unbounded + } +} + +impl PartialOrd for BytesAffine { + fn partial_cmp(&self, other: &Self) -> Option { + match (self, other) { + (BytesAffine::Bytes(x), BytesAffine::Bytes(y)) => x.partial_cmp(y), + (BytesAffine::Bytes(_), BytesAffine::Unbounded) => Some(cmp::Ordering::Less), + (BytesAffine::Unbounded, BytesAffine::Bytes(_)) => Some(cmp::Ordering::Greater), + (BytesAffine::Unbounded, BytesAffine::Unbounded) => Some(cmp::Ordering::Equal), + } + } +} + +impl Ord for BytesAffine { + fn cmp(&self, other: &Self) -> cmp::Ordering { + match (self, other) { + (BytesAffine::Bytes(x), BytesAffine::Bytes(y)) => x.cmp(y), + (BytesAffine::Bytes(_), BytesAffine::Unbounded) => cmp::Ordering::Less, + (BytesAffine::Unbounded, BytesAffine::Bytes(_)) => cmp::Ordering::Greater, + (BytesAffine::Unbounded, BytesAffine::Unbounded) => cmp::Ordering::Equal, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn bytes_affine_cmp_is_ok() { + assert_eq!(BytesAffine::new_key("abc"), BytesAffine::new_key("abc")); + assert!(BytesAffine::new_key("a") < BytesAffine::new_key("b")); + assert!(BytesAffine::new_key("abcd") < BytesAffine::new_key("b")); + assert!(BytesAffine::new_key("abcd") < BytesAffine::new_unbounded()); + assert!(BytesAffine::new_key("123") < BytesAffine::new_unbounded()); + assert_eq!(BytesAffine::new_unbounded(), BytesAffine::new_unbounded()); + } +} diff --git a/crates/xlineapi/src/lib.rs b/crates/xlineapi/src/lib.rs index 35b9e2893..a6556397e 100644 --- a/crates/xlineapi/src/lib.rs +++ b/crates/xlineapi/src/lib.rs @@ -167,6 +167,7 @@ pub mod command; pub mod execute_error; +pub mod interval; pub mod request_validation; mod etcdserverpb {