1use crate::caller::{ClientCaller, ClientCallerBuilder};
4pub use crate::rpc::pb::etcdserverpb::compare::CompareResult as CompareOp;
5pub use crate::rpc::pb::etcdserverpb::range_request::{SortOrder, SortTarget};
6
7use crate::error::Result;
8use crate::intercept::InterceptedChannel;
9use crate::rpc::pb::etcdserverpb::compare::{CompareTarget, TargetUnion};
10use crate::rpc::pb::etcdserverpb::kv_client::KvClient as PbKvClient;
11use crate::rpc::pb::etcdserverpb::request_op::Request as PbTxnOp;
12use crate::rpc::pb::etcdserverpb::response_op::Response as PbTxnOpResponse;
13use crate::rpc::pb::etcdserverpb::{
14 CompactionRequest as PbCompactionRequest, CompactionRequest,
15 CompactionResponse as PbCompactionResponse, Compare as PbCompare,
16 DeleteRangeRequest as PbDeleteRequest, DeleteRangeRequest,
17 DeleteRangeResponse as PbDeleteResponse, PutRequest as PbPutRequest,
18 PutResponse as PbPutResponse, RangeRequest as PbRangeRequest, RangeResponse as PbRangeResponse,
19 RequestOp as PbTxnRequestOp, TxnRequest as PbTxnRequest, TxnResponse as PbTxnResponse,
20};
21use crate::rpc::{get_prefix, KeyRange, KeyValue, ResponseHeader};
22use crate::vec::VecExt;
23use std::mem::ManuallyDrop;
24use tonic::{IntoRequest, Request};
25
26type Client = PbKvClient<InterceptedChannel>;
27
28#[repr(transparent)]
30#[derive(Clone)]
31pub struct KvClient {
32 inner: ClientCaller<Client>,
33}
34
35impl KvClient {
36 #[inline]
38 pub(crate) fn new(builder: ClientCallerBuilder) -> Self {
39 Self {
40 inner: builder.build(Client::new),
41 }
42 }
43
44 pub fn max_decoding_message_size(mut self, limit: usize) -> Self {
48 self.inner = self
49 .inner
50 .with(|client| client.max_decoding_message_size(limit));
51 self
52 }
53
54 pub fn max_encoding_message_size(mut self, limit: usize) -> Self {
58 self.inner = self
59 .inner
60 .with(|client| client.max_encoding_message_size(limit));
61 self
62 }
63
64 #[inline]
68 pub async fn put(
69 &mut self,
70 key: impl Into<Vec<u8>>,
71 value: impl Into<Vec<u8>>,
72 options: Option<PutOptions>,
73 ) -> Result<PutResponse> {
74 async fn put_impl(client: &mut Client, req: PutOptions) -> Result<PutResponse> {
75 let resp = client.put(req).await?.into_inner();
76 Ok(PutResponse::new(resp))
77 }
78 self.inner
79 .do_call(options.unwrap_or_default().with_kv(key, value), put_impl)
80 .await
81 }
82
83 #[inline]
85 pub async fn get(
86 &mut self,
87 key: impl Into<Vec<u8>>,
88 options: Option<GetOptions>,
89 ) -> Result<GetResponse> {
90 async fn get_impl(client: &mut Client, req: GetOptions) -> Result<GetResponse> {
91 let resp = client.range(req).await?.into_inner();
92 Ok(GetResponse::new(resp))
93 }
94 self.inner
95 .do_call(options.unwrap_or_default().with_key(key.into()), get_impl)
96 .await
97 }
98
99 #[inline]
101 pub async fn delete(
102 &mut self,
103 key: impl Into<Vec<u8>>,
104 options: Option<DeleteOptions>,
105 ) -> Result<DeleteResponse> {
106 async fn delete_impl(client: &mut Client, req: DeleteOptions) -> Result<DeleteResponse> {
107 let resp = client.delete_range(req).await?.into_inner();
108 Ok(DeleteResponse::new(resp))
109 }
110 self.inner
111 .do_call(
112 options.unwrap_or_default().with_key(key.into()),
113 delete_impl,
114 )
115 .await
116 }
117
118 #[inline]
122 pub async fn compact(
123 &mut self,
124 revision: i64,
125 options: Option<CompactionOptions>,
126 ) -> Result<CompactionResponse> {
127 async fn compact_impl(
128 client: &mut Client,
129 req: CompactionOptions,
130 ) -> Result<CompactionResponse> {
131 let resp = client.compact(req).await?.into_inner();
132 Ok(CompactionResponse::new(resp))
133 }
134 self.inner
135 .do_call(
136 options.unwrap_or_default().with_revision(revision),
137 compact_impl,
138 )
139 .await
140 }
141
142 #[inline]
147 pub async fn txn(&mut self, txn: Txn) -> Result<TxnResponse> {
148 async fn txn_impl(client: &mut Client, txn: Txn) -> Result<TxnResponse> {
149 let resp = client.txn(txn).await?.into_inner();
150 Ok(TxnResponse::new(resp))
151 }
152 self.inner.do_call(txn, txn_impl).await
153 }
154}
155
156#[derive(Debug, Default, Clone)]
158#[repr(transparent)]
159pub struct PutOptions(PbPutRequest);
160
161impl PutOptions {
162 #[inline]
164 fn with_kv(mut self, key: impl Into<Vec<u8>>, value: impl Into<Vec<u8>>) -> Self {
165 self.0.key = key.into();
166 self.0.value = value.into();
167 self
168 }
169
170 #[inline]
172 pub const fn new() -> Self {
173 Self(PbPutRequest {
174 key: Vec::new(),
175 value: Vec::new(),
176 lease: 0,
177 prev_kv: false,
178 ignore_value: false,
179 ignore_lease: false,
180 })
181 }
182
183 #[inline]
186 pub const fn with_lease(mut self, lease: i64) -> Self {
187 self.0.lease = lease;
188 self
189 }
190
191 #[inline]
194 pub const fn with_prev_key(mut self) -> Self {
195 self.0.prev_kv = true;
196 self
197 }
198
199 #[inline]
202 pub const fn with_ignore_value(mut self) -> Self {
203 self.0.ignore_value = true;
204 self
205 }
206
207 #[inline]
210 pub const fn with_ignore_lease(mut self) -> Self {
211 self.0.ignore_lease = true;
212 self
213 }
214}
215
216impl From<PutOptions> for PbPutRequest {
217 #[inline]
218 fn from(options: PutOptions) -> Self {
219 options.0
220 }
221}
222
223impl IntoRequest<PbPutRequest> for PutOptions {
224 #[inline]
225 fn into_request(self) -> Request<PbPutRequest> {
226 Request::new(self.into())
227 }
228}
229
230#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
232#[derive(Debug, Clone)]
233#[repr(transparent)]
234pub struct PutResponse(PbPutResponse);
235
236impl PutResponse {
237 #[inline]
239 const fn new(resp: PbPutResponse) -> Self {
240 Self(resp)
241 }
242
243 #[inline]
245 pub fn header(&self) -> Option<&ResponseHeader> {
246 self.0.header.as_ref().map(From::from)
247 }
248
249 #[inline]
251 pub fn take_header(&mut self) -> Option<ResponseHeader> {
252 self.0.header.take().map(ResponseHeader::new)
253 }
254
255 #[inline]
257 pub fn prev_key(&self) -> Option<&KeyValue> {
258 self.0.prev_kv.as_ref().map(From::from)
259 }
260
261 #[inline]
263 pub fn take_prev_key(&mut self) -> Option<KeyValue> {
264 self.0.prev_kv.take().map(KeyValue::new)
265 }
266
267 #[inline]
268 pub(crate) fn strip_prev_key_prefix(&mut self, prefix: &[u8]) {
269 if let Some(kv) = self.0.prev_kv.as_mut() {
270 kv.key.strip_key_prefix(prefix);
271 }
272 }
273}
274
275#[derive(Debug, Default, Clone)]
277pub struct GetOptions {
278 req: PbRangeRequest,
279 key_range: KeyRange,
280}
281
282impl GetOptions {
283 #[inline]
285 fn with_key(mut self, key: impl Into<Vec<u8>>) -> Self {
286 self.key_range.with_key(key);
287 self
288 }
289
290 #[inline]
292 pub const fn new() -> Self {
293 Self {
294 req: PbRangeRequest {
295 key: Vec::new(),
296 range_end: Vec::new(),
297 limit: 0,
298 revision: 0,
299 sort_order: 0,
300 sort_target: 0,
301 serializable: false,
302 keys_only: false,
303 count_only: false,
304 min_mod_revision: 0,
305 max_mod_revision: 0,
306 min_create_revision: 0,
307 max_create_revision: 0,
308 },
309 key_range: KeyRange::new(),
310 }
311 }
312
313 #[inline]
317 pub fn with_range(mut self, end_key: impl Into<Vec<u8>>) -> Self {
318 self.key_range.with_range(end_key);
319 self
320 }
321
322 #[inline]
324 pub fn with_from_key(mut self) -> Self {
325 self.key_range.with_from_key();
326 self
327 }
328
329 #[inline]
331 pub fn with_prefix(mut self) -> Self {
332 self.key_range.with_prefix();
333 self
334 }
335
336 #[inline]
338 pub fn with_all_keys(mut self) -> Self {
339 self.key_range.with_all_keys();
340 self
341 }
342
343 #[inline]
346 pub const fn with_limit(mut self, limit: i64) -> Self {
347 self.req.limit = limit;
348 self
349 }
350
351 #[inline]
355 pub const fn with_revision(mut self, revision: i64) -> Self {
356 self.req.revision = revision;
357 self
358 }
359
360 #[inline]
363 pub fn with_sort(mut self, target: SortTarget, order: SortOrder) -> Self {
364 if target == SortTarget::Key && order == SortOrder::Ascend {
365 self.req.sort_order = SortOrder::None as i32;
371 } else {
372 self.req.sort_order = order as i32;
373 }
374 self.req.sort_target = target as i32;
375 self
376 }
377
378 #[inline]
385 pub const fn with_serializable(mut self) -> Self {
386 self.req.serializable = true;
387 self
388 }
389
390 #[inline]
392 pub const fn with_keys_only(mut self) -> Self {
393 self.req.keys_only = true;
394 self
395 }
396
397 #[inline]
399 pub const fn with_count_only(mut self) -> Self {
400 self.req.count_only = true;
401 self
402 }
403
404 #[inline]
407 pub const fn with_min_mod_revision(mut self, revision: i64) -> Self {
408 self.req.min_mod_revision = revision;
409 self
410 }
411
412 #[inline]
415 pub const fn with_max_mod_revision(mut self, revision: i64) -> Self {
416 self.req.max_mod_revision = revision;
417 self
418 }
419
420 #[inline]
423 pub const fn with_min_create_revision(mut self, revision: i64) -> Self {
424 self.req.min_create_revision = revision;
425 self
426 }
427
428 #[inline]
431 pub const fn with_max_create_revision(mut self, revision: i64) -> Self {
432 self.req.max_create_revision = revision;
433 self
434 }
435
436 #[inline]
437 pub(crate) fn key_range_end_mut(&mut self) -> &mut Vec<u8> {
438 &mut self.key_range.range_end
439 }
440}
441
442impl From<GetOptions> for PbRangeRequest {
443 #[inline]
444 fn from(mut options: GetOptions) -> Self {
445 let (key, rang_end) = options.key_range.build();
446 options.req.key = key;
447 options.req.range_end = rang_end;
448 options.req
449 }
450}
451
452impl IntoRequest<PbRangeRequest> for GetOptions {
453 #[inline]
454 fn into_request(self) -> Request<PbRangeRequest> {
455 Request::new(self.into())
456 }
457}
458
459#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
461#[derive(Debug, Clone)]
462#[repr(transparent)]
463pub struct GetResponse(PbRangeResponse);
464
465impl GetResponse {
466 #[inline]
468 const fn new(resp: PbRangeResponse) -> Self {
469 Self(resp)
470 }
471
472 #[inline]
474 pub fn header(&self) -> Option<&ResponseHeader> {
475 self.0.header.as_ref().map(From::from)
476 }
477
478 #[inline]
480 pub fn take_header(&mut self) -> Option<ResponseHeader> {
481 self.0.header.take().map(ResponseHeader::new)
482 }
483
484 #[inline]
487 pub fn kvs(&self) -> &[KeyValue] {
488 unsafe { &*(self.0.kvs.as_slice() as *const _ as *const [KeyValue]) }
489 }
490
491 #[inline]
493 pub fn take_kvs(&mut self) -> Vec<KeyValue> {
494 let kvs = ManuallyDrop::new(std::mem::take(&mut self.0.kvs));
495 unsafe { Vec::from_raw_parts(kvs.as_ptr() as *mut KeyValue, kvs.len(), kvs.capacity()) }
496 }
497
498 #[inline]
499 pub(crate) fn strip_kvs_prefix(&mut self, prefix: &[u8]) {
500 for kv in self.0.kvs.iter_mut() {
501 kv.key.strip_key_prefix(prefix);
502 }
503 }
504
505 #[inline]
507 pub const fn more(&self) -> bool {
508 self.0.more
509 }
510
511 #[inline]
513 pub const fn count(&self) -> i64 {
514 self.0.count
515 }
516}
517
518#[derive(Debug, Default, Clone)]
520pub struct DeleteOptions {
521 req: PbDeleteRequest,
522 key_range: KeyRange,
523}
524
525impl DeleteOptions {
526 #[inline]
528 fn with_key(mut self, key: impl Into<Vec<u8>>) -> Self {
529 self.key_range.with_key(key);
530 self
531 }
532
533 #[inline]
535 pub const fn new() -> Self {
536 Self {
537 req: PbDeleteRequest {
538 key: Vec::new(),
539 range_end: Vec::new(),
540 prev_kv: false,
541 },
542 key_range: KeyRange::new(),
543 }
544 }
545
546 #[inline]
548 pub fn with_range(mut self, end_key: impl Into<Vec<u8>>) -> Self {
549 self.key_range.with_range(end_key);
550 self
551 }
552
553 #[inline]
555 pub fn with_from_key(mut self) -> Self {
556 self.key_range.with_from_key();
557 self
558 }
559
560 #[inline]
562 pub fn with_prefix(mut self) -> Self {
563 self.key_range.with_prefix();
564 self
565 }
566
567 #[inline]
569 pub fn with_all_keys(mut self) -> Self {
570 self.key_range.with_all_keys();
571 self
572 }
573
574 #[inline]
577 pub const fn with_prev_key(mut self) -> Self {
578 self.req.prev_kv = true;
579 self
580 }
581
582 #[inline]
583 pub(crate) fn key_range_end_mut(&mut self) -> &mut Vec<u8> {
584 &mut self.key_range.range_end
585 }
586}
587
588impl From<DeleteOptions> for PbDeleteRequest {
589 #[inline]
590 fn from(mut options: DeleteOptions) -> Self {
591 let (key, rang_end) = options.key_range.build();
592 options.req.key = key;
593 options.req.range_end = rang_end;
594 options.req
595 }
596}
597
598impl IntoRequest<PbDeleteRequest> for DeleteOptions {
599 #[inline]
600 fn into_request(self) -> Request<DeleteRangeRequest> {
601 Request::new(self.into())
602 }
603}
604
605#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
607#[derive(Debug, Clone)]
608#[repr(transparent)]
609pub struct DeleteResponse(PbDeleteResponse);
610
611impl DeleteResponse {
612 #[inline]
614 const fn new(resp: PbDeleteResponse) -> Self {
615 Self(resp)
616 }
617
618 #[inline]
620 pub fn header(&self) -> Option<&ResponseHeader> {
621 self.0.header.as_ref().map(From::from)
622 }
623
624 #[inline]
626 pub fn take_header(&mut self) -> Option<ResponseHeader> {
627 self.0.header.take().map(ResponseHeader::new)
628 }
629
630 #[inline]
632 pub const fn deleted(&self) -> i64 {
633 self.0.deleted
634 }
635
636 #[inline]
638 pub fn prev_kvs(&self) -> &[KeyValue] {
639 unsafe { &*(self.0.prev_kvs.as_slice() as *const _ as *const [KeyValue]) }
640 }
641
642 #[inline]
644 pub fn take_prev_kvs(&mut self) -> Vec<KeyValue> {
645 let kvs = ManuallyDrop::new(std::mem::take(&mut self.0.prev_kvs));
646 unsafe { Vec::from_raw_parts(kvs.as_ptr() as *mut KeyValue, kvs.len(), kvs.capacity()) }
647 }
648
649 #[inline]
650 pub(crate) fn strip_prev_kvs_prefix(&mut self, prefix: &[u8]) {
651 for kv in self.0.prev_kvs.iter_mut() {
652 kv.key.strip_key_prefix(prefix);
653 }
654 }
655}
656
657#[derive(Debug, Default, Clone)]
659#[repr(transparent)]
660pub struct CompactionOptions(PbCompactionRequest);
661
662impl CompactionOptions {
663 #[inline]
665 pub const fn new() -> Self {
666 Self(PbCompactionRequest {
667 revision: 0,
668 physical: false,
669 })
670 }
671
672 #[inline]
674 const fn with_revision(mut self, revision: i64) -> Self {
675 self.0.revision = revision;
676 self
677 }
678
679 #[inline]
683 pub const fn with_physical(mut self) -> Self {
684 self.0.physical = true;
685 self
686 }
687}
688
689impl IntoRequest<PbCompactionRequest> for CompactionOptions {
690 #[inline]
691 fn into_request(self) -> Request<CompactionRequest> {
692 Request::new(self.0)
693 }
694}
695
696#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
698#[derive(Debug, Clone)]
699#[repr(transparent)]
700pub struct CompactionResponse(PbCompactionResponse);
701
702impl CompactionResponse {
703 #[inline]
705 const fn new(resp: PbCompactionResponse) -> Self {
706 Self(resp)
707 }
708
709 #[inline]
711 pub fn header(&self) -> Option<&ResponseHeader> {
712 self.0.header.as_ref().map(From::from)
713 }
714
715 #[inline]
717 pub fn take_header(&mut self) -> Option<ResponseHeader> {
718 self.0.header.take().map(ResponseHeader::new)
719 }
720}
721
722#[derive(Debug, Clone)]
724#[repr(transparent)]
725pub struct Compare(PbCompare);
726
727impl Compare {
728 #[inline]
730 fn new(
731 key: impl Into<Vec<u8>>,
732 cmp: CompareOp,
733 target: CompareTarget,
734 target_union: TargetUnion,
735 ) -> Self {
736 Self(PbCompare {
737 result: cmp as i32,
738 target: target as i32,
739 key: key.into(),
740 range_end: Vec::new(),
741 target_union: Some(target_union),
742 })
743 }
744
745 #[inline]
747 pub fn version(key: impl Into<Vec<u8>>, cmp: CompareOp, version: i64) -> Self {
748 Self::new(
749 key,
750 cmp,
751 CompareTarget::Version,
752 TargetUnion::Version(version),
753 )
754 }
755
756 #[inline]
758 pub fn create_revision(key: impl Into<Vec<u8>>, cmp: CompareOp, revision: i64) -> Self {
759 Self::new(
760 key,
761 cmp,
762 CompareTarget::Create,
763 TargetUnion::CreateRevision(revision),
764 )
765 }
766
767 #[inline]
769 pub fn mod_revision(key: impl Into<Vec<u8>>, cmp: CompareOp, revision: i64) -> Self {
770 Self::new(
771 key,
772 cmp,
773 CompareTarget::Mod,
774 TargetUnion::ModRevision(revision),
775 )
776 }
777
778 #[inline]
780 pub fn value(key: impl Into<Vec<u8>>, cmp: CompareOp, value: impl Into<Vec<u8>>) -> Self {
781 Self::new(
782 key,
783 cmp,
784 CompareTarget::Value,
785 TargetUnion::Value(value.into()),
786 )
787 }
788
789 #[inline]
791 pub fn lease(key: impl Into<Vec<u8>>, cmp: CompareOp, lease: i64) -> Self {
792 Self::new(key, cmp, CompareTarget::Lease, TargetUnion::Lease(lease))
793 }
794
795 #[inline]
797 pub fn with_range(mut self, end: impl Into<Vec<u8>>) -> Self {
798 self.0.range_end = end.into();
799 self
800 }
801
802 #[inline]
804 pub fn with_prefix(mut self) -> Self {
805 self.0.range_end = get_prefix(&self.0.key);
806 self
807 }
808}
809
810#[derive(Debug, Clone)]
812#[repr(transparent)]
813pub struct TxnOp(PbTxnOp);
814
815impl TxnOp {
816 #[inline]
818 pub fn put(
819 key: impl Into<Vec<u8>>,
820 value: impl Into<Vec<u8>>,
821 options: Option<PutOptions>,
822 ) -> Self {
823 TxnOp(PbTxnOp::RequestPut(
824 options.unwrap_or_default().with_kv(key, value).into(),
825 ))
826 }
827
828 #[inline]
830 pub fn get(key: impl Into<Vec<u8>>, options: Option<GetOptions>) -> Self {
831 TxnOp(PbTxnOp::RequestRange(
832 options.unwrap_or_default().with_key(key).into(),
833 ))
834 }
835
836 #[inline]
838 pub fn delete(key: impl Into<Vec<u8>>, options: Option<DeleteOptions>) -> Self {
839 TxnOp(PbTxnOp::RequestDeleteRange(
840 options.unwrap_or_default().with_key(key).into(),
841 ))
842 }
843
844 #[inline]
846 pub fn txn(txn: Txn) -> Self {
847 TxnOp(PbTxnOp::RequestTxn(txn.into()))
848 }
849}
850
851impl From<TxnOp> for PbTxnOp {
852 #[inline]
853 fn from(op: TxnOp) -> Self {
854 op.0
855 }
856}
857
858#[derive(Debug, Default, Clone)]
860pub struct Txn {
861 req: PbTxnRequest,
862 c_when: bool,
863 c_then: bool,
864 c_else: bool,
865}
866
867impl Txn {
868 #[inline]
870 pub const fn new() -> Self {
871 Self {
872 req: PbTxnRequest {
873 compare: Vec::new(),
874 success: Vec::new(),
875 failure: Vec::new(),
876 },
877 c_when: false,
878 c_then: false,
879 c_else: false,
880 }
881 }
882
883 #[inline]
887 pub fn when(mut self, compares: impl Into<Vec<Compare>>) -> Self {
888 assert!(!self.c_when, "cannot call when twice");
889 assert!(!self.c_then, "cannot call when after and_then");
890 assert!(!self.c_else, "cannot call when after or_else");
891
892 self.c_when = true;
893
894 let compares = ManuallyDrop::new(compares.into());
895 self.req.compare = unsafe {
896 Vec::from_raw_parts(
897 compares.as_ptr() as *mut PbCompare,
898 compares.len(),
899 compares.capacity(),
900 )
901 };
902
903 self
904 }
905
906 #[inline]
909 pub fn and_then(mut self, operations: impl Into<Vec<TxnOp>>) -> Self {
910 assert!(!self.c_then, "cannot call and_then twice");
911 assert!(!self.c_else, "cannot call and_then after or_else");
912
913 self.c_then = true;
914 self.req.success = operations
915 .into()
916 .into_iter()
917 .map(|op| PbTxnRequestOp {
918 request: Some(op.into()),
919 })
920 .collect();
921 self
922 }
923
924 #[inline]
927 pub fn or_else(mut self, operations: impl Into<Vec<TxnOp>>) -> Self {
928 assert!(!self.c_else, "cannot call or_else twice");
929
930 self.c_else = true;
931 self.req.failure = operations
932 .into()
933 .into_iter()
934 .map(|op| PbTxnRequestOp {
935 request: Some(op.into()),
936 })
937 .collect();
938 self
939 }
940
941 #[inline]
942 pub(crate) fn prefix_with(&mut self, prefix: &[u8]) {
943 self.req.prefix_with(prefix);
944 }
945}
946
947impl PbTxnRequest {
948 fn prefix_with(&mut self, prefix: &[u8]) {
949 let prefix_op = |op: &mut PbTxnRequestOp| {
950 if let Some(request) = &mut op.request {
951 match request {
952 PbTxnOp::RequestRange(req) => {
953 req.key.prefix_with(prefix);
954 req.range_end.prefix_range_end_with(prefix);
955 }
956 PbTxnOp::RequestPut(req) => {
957 req.key.prefix_with(prefix);
958 }
959 PbTxnOp::RequestDeleteRange(req) => {
960 req.key.prefix_with(prefix);
961 req.range_end.prefix_range_end_with(prefix);
962 }
963 PbTxnOp::RequestTxn(req) => {
964 req.prefix_with(prefix);
965 }
966 }
967 }
968 };
969
970 self.compare.iter_mut().for_each(|cmp| {
971 cmp.key.prefix_with(prefix);
972 cmp.range_end.prefix_range_end_with(prefix);
973 });
974 self.success.iter_mut().for_each(prefix_op);
975 self.failure.iter_mut().for_each(prefix_op);
976 }
977}
978
979impl From<Txn> for PbTxnRequest {
980 #[inline]
981 fn from(txn: Txn) -> Self {
982 txn.req
983 }
984}
985
986impl IntoRequest<PbTxnRequest> for Txn {
987 #[inline]
988 fn into_request(self) -> Request<PbTxnRequest> {
989 Request::new(self.into())
990 }
991}
992
993#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
995#[derive(Debug, Clone)]
996pub enum TxnOpResponse {
997 Put(PutResponse),
998 Get(GetResponse),
999 Delete(DeleteResponse),
1000 Txn(TxnResponse),
1001}
1002
1003#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
1005#[derive(Debug, Clone)]
1006#[repr(transparent)]
1007pub struct TxnResponse(PbTxnResponse);
1008
1009impl TxnResponse {
1010 #[inline]
1012 const fn new(resp: PbTxnResponse) -> Self {
1013 Self(resp)
1014 }
1015
1016 #[inline]
1018 pub fn header(&self) -> Option<&ResponseHeader> {
1019 self.0.header.as_ref().map(From::from)
1020 }
1021
1022 #[inline]
1024 pub fn take_header(&mut self) -> Option<ResponseHeader> {
1025 self.0.header.take().map(ResponseHeader::new)
1026 }
1027
1028 #[inline]
1030 pub const fn succeeded(&self) -> bool {
1031 self.0.succeeded
1032 }
1033
1034 #[inline]
1036 pub fn op_responses(&self) -> Vec<TxnOpResponse> {
1037 self.0
1038 .responses
1039 .iter()
1040 .map(|resp| match resp.response.as_ref().unwrap() {
1041 PbTxnOpResponse::ResponsePut(put) => {
1042 TxnOpResponse::Put(PutResponse::new(put.clone()))
1043 }
1044 PbTxnOpResponse::ResponseRange(get) => {
1045 TxnOpResponse::Get(GetResponse::new(get.clone()))
1046 }
1047 PbTxnOpResponse::ResponseDeleteRange(delete) => {
1048 TxnOpResponse::Delete(DeleteResponse::new(delete.clone()))
1049 }
1050 PbTxnOpResponse::ResponseTxn(txn) => {
1051 TxnOpResponse::Txn(TxnResponse::new(txn.clone()))
1052 }
1053 })
1054 .collect()
1055 }
1056
1057 #[inline]
1058 pub(crate) fn strip_key_prefix(&mut self, prefix: &[u8]) {
1059 self.0.strip_key_prefix(prefix);
1060 }
1061}
1062
1063impl PbTxnResponse {
1064 fn strip_key_prefix(&mut self, prefix: &[u8]) {
1065 self.responses.iter_mut().for_each(|op| {
1066 if let Some(resp) = &mut op.response {
1067 match resp {
1068 PbTxnOpResponse::ResponseRange(r) => {
1069 for kv in r.kvs.iter_mut() {
1070 kv.key.strip_key_prefix(prefix);
1071 }
1072 }
1073 PbTxnOpResponse::ResponsePut(r) => {
1074 if let Some(kv) = r.prev_kv.as_mut() {
1075 kv.key.strip_key_prefix(prefix);
1076 }
1077 }
1078 PbTxnOpResponse::ResponseDeleteRange(r) => {
1079 for kv in r.prev_kvs.iter_mut() {
1080 kv.key.strip_key_prefix(prefix);
1081 }
1082 }
1083 PbTxnOpResponse::ResponseTxn(r) => {
1084 r.strip_key_prefix(prefix);
1085 }
1086 }
1087 }
1088 });
1089 }
1090}