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