inve_etcd/kv/
txn.rs

1use super::{
2    DeleteRequest, DeleteResponse, KeyRange, PutRequest, PutResponse, RangeRequest, RangeResponse,
3};
4use crate::proto::etcdserverpb;
5use crate::ResponseHeader;
6use etcdserverpb::compare::{CompareResult, CompareTarget, TargetUnion};
7use etcdserverpb::Compare;
8
9#[derive(Debug)]
10pub struct TxnRequest {
11    proto: etcdserverpb::TxnRequest,
12}
13
14impl TxnRequest {
15    pub fn new() -> Self {
16        Self {
17            proto: etcdserverpb::TxnRequest {
18                compare: vec![],
19                success: vec![],
20                failure: vec![],
21            },
22        }
23    }
24
25    pub fn when_version(mut self, key_range: KeyRange, cmp: TxnCmp, version: usize) -> Self {
26        let result: CompareResult = cmp.into();
27        self.proto.compare.push(Compare {
28            result: result as i32,
29            target: CompareTarget::Version as i32,
30            key: key_range.key,
31            range_end: key_range.range_end,
32            target_union: Some(TargetUnion::Version(version as i64)),
33        });
34        self
35    }
36
37    pub fn when_create_revision(
38        mut self,
39        key_range: KeyRange,
40        cmp: TxnCmp,
41        revision: usize,
42    ) -> Self {
43        let result: CompareResult = cmp.into();
44        self.proto.compare.push(Compare {
45            result: result as i32,
46            target: CompareTarget::Create as i32,
47            key: key_range.key,
48            range_end: key_range.range_end,
49            target_union: Some(TargetUnion::CreateRevision(revision as i64)),
50        });
51        self
52    }
53
54    pub fn when_mod_revision(mut self, key_range: KeyRange, cmp: TxnCmp, revision: usize) -> Self {
55        let result: CompareResult = cmp.into();
56        self.proto.compare.push(Compare {
57            result: result as i32,
58            target: CompareTarget::Mod as i32,
59            key: key_range.key,
60            range_end: key_range.range_end,
61            target_union: Some(TargetUnion::ModRevision(revision as i64)),
62        });
63        self
64    }
65
66    pub fn when_value<V>(mut self, key_range: KeyRange, cmp: TxnCmp, value: V) -> Self
67    where
68        V: Into<Vec<u8>>,
69    {
70        let result: CompareResult = cmp.into();
71        self.proto.compare.push(Compare {
72            result: result as i32,
73            target: CompareTarget::Value as i32,
74            key: key_range.key,
75            range_end: key_range.range_end,
76            target_union: Some(TargetUnion::Value(value.into())),
77        });
78        self
79    }
80
81    pub fn and_then<O>(mut self, op: O) -> Self
82    where
83        O: Into<TxnOp>,
84    {
85        self.proto.success.push(op.into().into());
86        self
87    }
88
89    pub fn or_else<O>(mut self, op: O) -> Self
90    where
91        O: Into<TxnOp>,
92    {
93        self.proto.failure.push(op.into().into());
94        self
95    }
96}
97
98impl Default for TxnRequest {
99    fn default() -> Self {
100        Self::new()
101    }
102}
103
104impl From<TxnRequest> for crate::proto::etcdserverpb::TxnRequest {
105    fn from(x: TxnRequest) -> Self {
106        x.proto
107    }
108}
109
110pub enum TxnOp {
111    Range(RangeRequest),
112    Put(PutRequest),
113    Delete(DeleteRequest),
114    Txn(TxnRequest),
115}
116
117impl From<TxnOp> for etcdserverpb::RequestOp {
118    fn from(x: TxnOp) -> etcdserverpb::RequestOp {
119        use etcdserverpb::request_op::Request;
120
121        let req = match x {
122            TxnOp::Range(req) => Request::RequestRange(req.into()),
123            TxnOp::Put(req) => Request::RequestPut(req.into()),
124            TxnOp::Delete(req) => Request::RequestDeleteRange(req.into()),
125            TxnOp::Txn(req) => Request::RequestTxn(req.into()),
126        };
127
128        etcdserverpb::RequestOp { request: Some(req) }
129    }
130}
131
132impl From<RangeRequest> for TxnOp {
133    fn from(req: RangeRequest) -> Self {
134        Self::Range(req)
135    }
136}
137
138impl From<PutRequest> for TxnOp {
139    fn from(req: PutRequest) -> Self {
140        Self::Put(req)
141    }
142}
143
144impl From<DeleteRequest> for TxnOp {
145    fn from(req: DeleteRequest) -> Self {
146        Self::Delete(req)
147    }
148}
149
150impl From<TxnRequest> for TxnOp {
151    fn from(req: TxnRequest) -> Self {
152        Self::Txn(req)
153    }
154}
155
156pub enum TxnCmp {
157    Equal,
158    NotEqual,
159    Greater,
160    Less,
161}
162
163impl From<TxnCmp> for CompareResult {
164    fn from(x: TxnCmp) -> CompareResult {
165        match x {
166            TxnCmp::Equal => CompareResult::Equal,
167            TxnCmp::NotEqual => CompareResult::NotEqual,
168            TxnCmp::Greater => CompareResult::Greater,
169            TxnCmp::Less => CompareResult::Less,
170        }
171    }
172}
173
174#[derive(Debug, Clone)]
175pub enum TxnOpResponse {
176    Range(RangeResponse),
177    Put(PutResponse),
178    Delete(DeleteResponse),
179    Txn(TxnResponse),
180}
181
182impl From<etcdserverpb::ResponseOp> for TxnOpResponse {
183    fn from(mut resp: etcdserverpb::ResponseOp) -> Self {
184        use etcdserverpb::response_op::Response;
185        match resp.response.take().unwrap() {
186            Response::ResponseRange(r) => Self::Range(From::from(r)),
187            Response::ResponsePut(r) => Self::Put(From::from(r)),
188            Response::ResponseTxn(r) => Self::Txn(From::from(r)),
189            Response::ResponseDeleteRange(r) => Self::Delete(From::from(r)),
190        }
191    }
192}
193
194#[derive(Debug, Clone)]
195pub struct TxnResponse {
196    pub header: ResponseHeader,
197    pub succeeded: bool,
198    pub responses: Vec<TxnOpResponse>,
199}
200
201impl From<etcdserverpb::TxnResponse> for TxnResponse {
202    fn from(proto: etcdserverpb::TxnResponse) -> Self {
203        Self {
204            header: From::from(proto.header.expect("must fetch header")),
205            succeeded: proto.succeeded,
206            responses: proto.responses.into_iter().map(From::from).collect(),
207        }
208    }
209}