ya_etcd_rs/kv/
mod.rs

1mod compact;
2mod delete;
3mod put;
4mod range;
5mod txn;
6
7pub use compact::{CompactRequest, CompactResponse};
8pub use delete::{DeleteRequest, DeleteResponse};
9pub use put::{PutRequest, PutResponse};
10pub use range::{RangeRequest, RangeResponse};
11pub use txn::{TxnCmp, TxnOp, TxnOpResponse, TxnRequest, TxnResponse};
12
13use std::{future::Future, ops::Range};
14
15use crate::Result;
16use crate::lease::LeaseId;
17use crate::proto::mvccpb;
18
19pub trait KeyValueOp {
20    fn put<R>(&self, req: R) -> impl Future<Output = Result<PutResponse>>
21    where
22        R: Into<PutRequest>;
23
24    fn get<R>(&self, req: R) -> impl Future<Output = Result<RangeResponse>>
25    where
26        R: Into<RangeRequest>;
27    fn get_all(&self) -> impl Future<Output = Result<RangeResponse>>;
28    fn get_by_prefix<K>(&self, p: K) -> impl Future<Output = Result<RangeResponse>>
29    where
30        K: Into<Vec<u8>>;
31    fn get_range<F, E>(&self, from: F, end: E) -> impl Future<Output = Result<RangeResponse>>
32    where
33        F: Into<Vec<u8>>,
34        E: Into<Vec<u8>>;
35
36    fn delete<R>(&self, req: R) -> impl Future<Output = Result<DeleteResponse>>
37    where
38        R: Into<DeleteRequest>;
39    fn delete_all(&self) -> impl Future<Output = Result<DeleteResponse>>;
40    fn delete_by_prefix<K>(&self, p: K) -> impl Future<Output = Result<DeleteResponse>>
41    where
42        K: Into<Vec<u8>>;
43    fn delete_range<F, E>(&self, from: F, end: E) -> impl Future<Output = Result<DeleteResponse>>
44    where
45        F: Into<Vec<u8>>,
46        E: Into<Vec<u8>>;
47
48    fn txn<R>(&self, req: R) -> impl Future<Output = Result<TxnResponse>>
49    where
50        R: Into<TxnRequest>;
51
52    fn compact<R>(&self, req: R) -> impl Future<Output = Result<CompactResponse>>
53    where
54        R: Into<CompactRequest>;
55}
56
57/// Key-Value pair.
58#[derive(Clone, PartialEq, Default, Debug)]
59pub struct KeyValue {
60    pub key: Vec<u8>,
61    pub value: Vec<u8>,
62    pub create_revision: i64,
63    pub mod_revision: i64,
64    pub version: i64,
65    pub lease: LeaseId,
66}
67
68impl KeyValue {
69    /// Converts the key from bytes `&[u8]` to `&str`.
70    /// Leaves the original `&[u8]` in place, and creates a new string slice containing the entire content.
71    pub fn key_str(&self) -> &str {
72        std::str::from_utf8(&self.key).expect("convert bytes to string")
73    }
74
75    /// Converts the value from bytes `&[u8]` to `&str`.
76    /// Leaves the original `&[u8]` in place, and creates a new string slice containing the entire content.
77    pub fn value_str(&self) -> &str {
78        std::str::from_utf8(&self.value).expect("convert bytes to string")
79    }
80}
81
82impl From<mvccpb::KeyValue> for KeyValue {
83    fn from(proto: mvccpb::KeyValue) -> Self {
84        Self {
85            key: proto.key,
86            value: proto.value,
87            create_revision: proto.create_revision,
88            mod_revision: proto.mod_revision,
89            version: proto.version,
90            lease: proto.lease,
91        }
92    }
93}
94
95/// KeyRange is an abstraction for describing etcd key of various types.
96#[derive(Clone, Hash, PartialEq, Eq)]
97pub struct KeyRange {
98    pub key: Vec<u8>,
99    pub range_end: Vec<u8>,
100}
101
102impl KeyRange {
103    /// Creates a new KeyRange for describing a range of multiple keys.
104    pub fn range<K, R>(key: K, range_end: R) -> Self
105    where
106        K: Into<Vec<u8>>,
107        R: Into<Vec<u8>>,
108    {
109        Self {
110            key: key.into(),
111            range_end: range_end.into(),
112        }
113    }
114
115    /// Creates a new KeyRange for describing a specified key.
116    pub fn key<K>(key: K) -> Self
117    where
118        K: Into<Vec<u8>>,
119    {
120        Self {
121            key: key.into(),
122            range_end: vec![],
123        }
124    }
125
126    /// Creates a new KeyRange for describing all keys.
127    pub fn all() -> Self {
128        Self {
129            key: vec![0],
130            range_end: vec![0],
131        }
132    }
133
134    /// Creates a new KeyRange for describing keys prefixed with specified value.
135    pub fn prefix<K>(prefix: K) -> Self
136    where
137        K: Into<Vec<u8>>,
138    {
139        let key = prefix.into();
140        if key.is_empty() {
141            // An empty Vec<u8> results in an invalid KeyRange.
142            // Assume that an empty value passed to this method implies no prefix (i.e., all keys).
143            return KeyRange::all();
144        }
145
146        let range_end = {
147            let mut end = key.clone();
148
149            for i in (0..end.len()).rev() {
150                if end[i] < 0xff {
151                    end[i] += 1;
152                    end.truncate(i + 1);
153                    break;
154                }
155            }
156            end
157        };
158        Self { key, range_end }
159    }
160}
161
162impl<T> From<Range<T>> for KeyRange
163where
164    T: Into<Vec<u8>>,
165{
166    fn from(range: Range<T>) -> Self {
167        Self::range(range.start, range.end)
168    }
169}
170
171impl From<&str> for KeyRange {
172    fn from(k: &str) -> Self {
173        Self::key(k)
174    }
175}
176
177impl From<String> for KeyRange {
178    fn from(k: String) -> Self {
179        Self::key(k)
180    }
181}