1use std::borrow::Cow;
2use std::marker;
3
4use heed_traits::LexicographicComparator;
5use types::LazyDecode;
6
7use crate::cursor::MoveOperation;
8use crate::envs::DefaultComparator;
9use crate::iteration_method::{IterationMethod, MoveBetweenKeys, MoveThroughDuplicateValues};
10use crate::*;
11
12fn advance_prefix<C: LexicographicComparator>(bytes: &mut [u8]) -> bool {
17 let mut idx = bytes.len();
18 while idx > 0 && bytes[idx - 1] == C::max_elem() {
19 idx -= 1;
20 }
21 if idx == 0 {
22 return false;
23 }
24 bytes[idx - 1] = C::successor(bytes[idx - 1]).expect("Cannot advance byte; this is a bug.");
25 for i in (idx + 1)..=bytes.len() {
26 bytes[i - 1] = C::min_elem();
27 }
28 true
29}
30
31fn retreat_prefix<C: LexicographicComparator>(bytes: &mut [u8]) -> bool {
36 let mut idx = bytes.len();
37 while idx > 0 && bytes[idx - 1] == C::min_elem() {
38 idx -= 1;
39 }
40 if idx == 0 {
41 return false;
42 }
43 bytes[idx - 1] = C::predecessor(bytes[idx - 1]).expect("Cannot retreat byte; this is a bug.");
44 for i in (idx + 1)..=bytes.len() {
45 bytes[i - 1] = C::max_elem();
46 }
47 true
48}
49
50fn move_on_prefix_end<'txn, C: LexicographicComparator>(
51 cursor: &mut RoCursor<'txn>,
52 prefix: &mut [u8],
53) -> Result<Option<(&'txn [u8], &'txn [u8])>> {
54 if advance_prefix::<C>(prefix) {
55 let result = cursor
56 .move_on_key_greater_than_or_equal_to(prefix)
57 .and_then(|_| cursor.move_on_prev(MoveOperation::NoDup));
58 retreat_prefix::<C>(prefix);
59 result
60 } else {
61 cursor.move_on_last(MoveOperation::NoDup)
63 }
64}
65
66pub struct RoPrefix<'txn, KC, DC, C = DefaultComparator, IM = MoveThroughDuplicateValues> {
68 cursor: RoCursor<'txn>,
69 prefix: Vec<u8>,
70 move_on_first: bool,
71 _phantom: marker::PhantomData<(KC, DC, C, IM)>,
72}
73
74impl<'txn, KC, DC, C, IM> RoPrefix<'txn, KC, DC, C, IM> {
75 pub(crate) fn new(cursor: RoCursor<'txn>, prefix: Vec<u8>) -> RoPrefix<'txn, KC, DC, C, IM> {
76 RoPrefix { cursor, prefix, move_on_first: true, _phantom: marker::PhantomData }
77 }
78
79 pub fn move_between_keys(self) -> RoPrefix<'txn, KC, DC, C, MoveBetweenKeys> {
83 RoPrefix {
84 cursor: self.cursor,
85 prefix: self.prefix,
86 move_on_first: self.move_on_first,
87 _phantom: marker::PhantomData,
88 }
89 }
90
91 pub fn move_through_duplicate_values(
95 self,
96 ) -> RoPrefix<'txn, KC, DC, C, MoveThroughDuplicateValues> {
97 RoPrefix {
98 cursor: self.cursor,
99 prefix: self.prefix,
100 move_on_first: self.move_on_first,
101 _phantom: marker::PhantomData,
102 }
103 }
104
105 pub fn remap_types<KC2, DC2>(self) -> RoPrefix<'txn, KC2, DC2, C, IM> {
107 RoPrefix {
108 cursor: self.cursor,
109 prefix: self.prefix,
110 move_on_first: self.move_on_first,
111 _phantom: marker::PhantomData,
112 }
113 }
114
115 pub fn remap_key_type<KC2>(self) -> RoPrefix<'txn, KC2, DC, C, IM> {
117 self.remap_types::<KC2, DC>()
118 }
119
120 pub fn remap_data_type<DC2>(self) -> RoPrefix<'txn, KC, DC2, C, IM> {
122 self.remap_types::<KC, DC2>()
123 }
124
125 pub fn lazily_decode_data(self) -> RoPrefix<'txn, KC, LazyDecode<DC>, C, IM> {
127 self.remap_types::<KC, LazyDecode<DC>>()
128 }
129}
130
131impl<'txn, KC, DC, C, IM> Iterator for RoPrefix<'txn, KC, DC, C, IM>
132where
133 KC: BytesDecode<'txn>,
134 DC: BytesDecode<'txn>,
135 C: LexicographicComparator,
136 IM: IterationMethod,
137{
138 type Item = Result<(KC::DItem, DC::DItem)>;
139
140 fn next(&mut self) -> Option<Self::Item> {
141 let result = if self.move_on_first {
142 self.move_on_first = false;
143 self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix)
144 } else {
145 self.cursor.move_on_next(IM::MOVE_OPERATION)
146 };
147
148 match result {
149 Ok(Some((key, data))) => {
150 if key.starts_with(&self.prefix) {
151 match (KC::bytes_decode(key), DC::bytes_decode(data)) {
152 (Ok(key), Ok(data)) => Some(Ok((key, data))),
153 (Err(e), _) | (_, Err(e)) => Some(Err(Error::Decoding(e))),
154 }
155 } else {
156 None
157 }
158 }
159 Ok(None) => None,
160 Err(e) => Some(Err(e)),
161 }
162 }
163
164 fn last(mut self) -> Option<Self::Item> {
165 let result = if self.move_on_first {
166 move_on_prefix_end::<C>(&mut self.cursor, &mut self.prefix)
167 } else {
168 match (
169 self.cursor.current(),
170 move_on_prefix_end::<C>(&mut self.cursor, &mut self.prefix),
171 ) {
172 (Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
173 Ok(Some((key, data)))
174 }
175 (Ok(_), Ok(_)) => Ok(None),
176 (Err(e), _) | (_, Err(e)) => Err(e),
177 }
178 };
179
180 match result {
181 Ok(Some((key, data))) => {
182 if key.starts_with(&self.prefix) {
183 match (KC::bytes_decode(key), DC::bytes_decode(data)) {
184 (Ok(key), Ok(data)) => Some(Ok((key, data))),
185 (Err(e), _) | (_, Err(e)) => Some(Err(Error::Decoding(e))),
186 }
187 } else {
188 None
189 }
190 }
191 Ok(None) => None,
192 Err(e) => Some(Err(e)),
193 }
194 }
195}
196
197impl<KC, DC, C, IM> fmt::Debug for RoPrefix<'_, KC, DC, C, IM> {
198 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199 f.debug_struct("RoPrefix").finish()
200 }
201}
202
203pub struct RwPrefix<'txn, KC, DC, C = DefaultComparator, IM = MoveThroughDuplicateValues> {
205 cursor: RwCursor<'txn>,
206 prefix: Vec<u8>,
207 move_on_first: bool,
208 _phantom: marker::PhantomData<(KC, DC, C, IM)>,
209}
210
211impl<'txn, KC, DC, C, IM> RwPrefix<'txn, KC, DC, C, IM> {
212 pub(crate) fn new(cursor: RwCursor<'txn>, prefix: Vec<u8>) -> RwPrefix<'txn, KC, DC, C, IM> {
213 RwPrefix { cursor, prefix, move_on_first: true, _phantom: marker::PhantomData }
214 }
215
216 pub unsafe fn del_current(&mut self) -> Result<bool> {
230 self.cursor.del_current()
231 }
232
233 pub unsafe fn put_current<'a>(
257 &mut self,
258 key: &'a KC::EItem,
259 data: &'a DC::EItem,
260 ) -> Result<bool>
261 where
262 KC: BytesEncode<'a>,
263 DC: BytesEncode<'a>,
264 {
265 let key_bytes: Cow<[u8]> = KC::bytes_encode(key).map_err(Error::Encoding)?;
266 let data_bytes: Cow<[u8]> = DC::bytes_encode(data).map_err(Error::Encoding)?;
267 self.cursor.put_current(&key_bytes, &data_bytes)
268 }
269
270 pub unsafe fn put_current_reserved_with_flags<'a, F>(
284 &mut self,
285 flags: PutFlags,
286 key: &'a KC::EItem,
287 data_size: usize,
288 write_func: F,
289 ) -> Result<bool>
290 where
291 KC: BytesEncode<'a>,
292 F: FnOnce(&mut ReservedSpace) -> io::Result<()>,
293 {
294 let key_bytes: Cow<[u8]> = KC::bytes_encode(key).map_err(Error::Encoding)?;
295 self.cursor.put_current_reserved_with_flags(flags, &key_bytes, data_size, write_func)
296 }
297
298 pub unsafe fn put_current_with_options<'a, NDC>(
316 &mut self,
317 flags: PutFlags,
318 key: &'a KC::EItem,
319 data: &'a NDC::EItem,
320 ) -> Result<()>
321 where
322 KC: BytesEncode<'a>,
323 NDC: BytesEncode<'a>,
324 {
325 let key_bytes: Cow<[u8]> = KC::bytes_encode(key).map_err(Error::Encoding)?;
326 let data_bytes: Cow<[u8]> = NDC::bytes_encode(data).map_err(Error::Encoding)?;
327 self.cursor.put_current_with_flags(flags, &key_bytes, &data_bytes)
328 }
329
330 pub fn move_between_keys(self) -> RwPrefix<'txn, KC, DC, C, MoveBetweenKeys> {
334 RwPrefix {
335 cursor: self.cursor,
336 prefix: self.prefix,
337 move_on_first: self.move_on_first,
338 _phantom: marker::PhantomData,
339 }
340 }
341
342 pub fn move_through_duplicate_values(
346 self,
347 ) -> RwPrefix<'txn, KC, DC, C, MoveThroughDuplicateValues> {
348 RwPrefix {
349 cursor: self.cursor,
350 prefix: self.prefix,
351 move_on_first: self.move_on_first,
352 _phantom: marker::PhantomData,
353 }
354 }
355
356 pub fn remap_types<KC2, DC2>(self) -> RwPrefix<'txn, KC2, DC2, C, IM> {
358 RwPrefix {
359 cursor: self.cursor,
360 prefix: self.prefix,
361 move_on_first: self.move_on_first,
362 _phantom: marker::PhantomData,
363 }
364 }
365
366 pub fn remap_key_type<KC2>(self) -> RwPrefix<'txn, KC2, DC, C, IM> {
368 self.remap_types::<KC2, DC>()
369 }
370
371 pub fn remap_data_type<DC2>(self) -> RwPrefix<'txn, KC, DC2, C, IM> {
373 self.remap_types::<KC, DC2>()
374 }
375
376 pub fn lazily_decode_data(self) -> RwPrefix<'txn, KC, LazyDecode<DC>, C, IM> {
378 self.remap_types::<KC, LazyDecode<DC>>()
379 }
380}
381
382impl<'txn, KC, DC, C, IM> Iterator for RwPrefix<'txn, KC, DC, C, IM>
383where
384 KC: BytesDecode<'txn>,
385 DC: BytesDecode<'txn>,
386 C: LexicographicComparator,
387 IM: IterationMethod,
388{
389 type Item = Result<(KC::DItem, DC::DItem)>;
390
391 fn next(&mut self) -> Option<Self::Item> {
392 let result = if self.move_on_first {
393 self.move_on_first = false;
394 self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix)
395 } else {
396 self.cursor.move_on_next(IM::MOVE_OPERATION)
397 };
398
399 match result {
400 Ok(Some((key, data))) => {
401 if key.starts_with(&self.prefix) {
402 match (KC::bytes_decode(key), DC::bytes_decode(data)) {
403 (Ok(key), Ok(data)) => Some(Ok((key, data))),
404 (Err(e), _) | (_, Err(e)) => Some(Err(Error::Decoding(e))),
405 }
406 } else {
407 None
408 }
409 }
410 Ok(None) => None,
411 Err(e) => Some(Err(e)),
412 }
413 }
414
415 fn last(mut self) -> Option<Self::Item> {
416 let result = if self.move_on_first {
417 move_on_prefix_end::<C>(&mut self.cursor, &mut self.prefix)
418 } else {
419 match (
420 self.cursor.current(),
421 move_on_prefix_end::<C>(&mut self.cursor, &mut self.prefix),
422 ) {
423 (Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
424 Ok(Some((key, data)))
425 }
426 (Ok(_), Ok(_)) => Ok(None),
427 (Err(e), _) | (_, Err(e)) => Err(e),
428 }
429 };
430
431 match result {
432 Ok(Some((key, data))) => {
433 if key.starts_with(&self.prefix) {
434 match (KC::bytes_decode(key), DC::bytes_decode(data)) {
435 (Ok(key), Ok(data)) => Some(Ok((key, data))),
436 (Err(e), _) | (_, Err(e)) => Some(Err(Error::Decoding(e))),
437 }
438 } else {
439 None
440 }
441 }
442 Ok(None) => None,
443 Err(e) => Some(Err(e)),
444 }
445 }
446}
447
448impl<KC, DC, C, IM> fmt::Debug for RwPrefix<'_, KC, DC, C, IM> {
449 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
450 f.debug_struct("RwPrefix").finish()
451 }
452}
453
454pub struct RoRevPrefix<'txn, KC, DC, C = DefaultComparator, IM = MoveThroughDuplicateValues> {
456 cursor: RoCursor<'txn>,
457 prefix: Vec<u8>,
458 move_on_last: bool,
459 _phantom: marker::PhantomData<(KC, DC, C, IM)>,
460}
461
462impl<'txn, KC, DC, C, IM> RoRevPrefix<'txn, KC, DC, C, IM> {
463 pub(crate) fn new(cursor: RoCursor<'txn>, prefix: Vec<u8>) -> RoRevPrefix<'txn, KC, DC, C, IM> {
464 RoRevPrefix { cursor, prefix, move_on_last: true, _phantom: marker::PhantomData }
465 }
466
467 pub fn move_between_keys(self) -> RoRevPrefix<'txn, KC, DC, C, MoveBetweenKeys> {
471 RoRevPrefix {
472 cursor: self.cursor,
473 prefix: self.prefix,
474 move_on_last: self.move_on_last,
475 _phantom: marker::PhantomData,
476 }
477 }
478
479 pub fn move_through_duplicate_values(
483 self,
484 ) -> RoRevPrefix<'txn, KC, DC, C, MoveThroughDuplicateValues> {
485 RoRevPrefix {
486 cursor: self.cursor,
487 prefix: self.prefix,
488 move_on_last: self.move_on_last,
489 _phantom: marker::PhantomData,
490 }
491 }
492
493 pub fn remap_types<KC2, DC2>(self) -> RoRevPrefix<'txn, KC2, DC2, C, IM> {
495 RoRevPrefix {
496 cursor: self.cursor,
497 prefix: self.prefix,
498 move_on_last: self.move_on_last,
499 _phantom: marker::PhantomData,
500 }
501 }
502
503 pub fn remap_key_type<KC2>(self) -> RoRevPrefix<'txn, KC2, DC, C, IM> {
505 self.remap_types::<KC2, DC>()
506 }
507
508 pub fn remap_data_type<DC2>(self) -> RoRevPrefix<'txn, KC, DC2, C, IM> {
510 self.remap_types::<KC, DC2>()
511 }
512
513 pub fn lazily_decode_data(self) -> RoRevPrefix<'txn, KC, LazyDecode<DC>, C, IM> {
515 self.remap_types::<KC, LazyDecode<DC>>()
516 }
517}
518
519impl<'txn, KC, DC, C, IM> Iterator for RoRevPrefix<'txn, KC, DC, C, IM>
520where
521 KC: BytesDecode<'txn>,
522 DC: BytesDecode<'txn>,
523 C: LexicographicComparator,
524 IM: IterationMethod,
525{
526 type Item = Result<(KC::DItem, DC::DItem)>;
527
528 fn next(&mut self) -> Option<Self::Item> {
529 let result = if self.move_on_last {
530 self.move_on_last = false;
531 move_on_prefix_end::<C>(&mut self.cursor, &mut self.prefix)
532 } else {
533 self.cursor.move_on_prev(IM::MOVE_OPERATION)
534 };
535
536 match result {
537 Ok(Some((key, data))) => {
538 if key.starts_with(&self.prefix) {
539 match (KC::bytes_decode(key), DC::bytes_decode(data)) {
540 (Ok(key), Ok(data)) => Some(Ok((key, data))),
541 (Err(e), _) | (_, Err(e)) => Some(Err(Error::Decoding(e))),
542 }
543 } else {
544 None
545 }
546 }
547 Ok(None) => None,
548 Err(e) => Some(Err(e)),
549 }
550 }
551
552 fn last(mut self) -> Option<Self::Item> {
553 let result = if self.move_on_last {
554 self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix)
555 } else {
556 let current = self.cursor.current();
557 let start = self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix);
558 match (current, start) {
559 (Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
560 Ok(Some((key, data)))
561 }
562 (Ok(_), Ok(_)) => Ok(None),
563 (Err(e), _) | (_, Err(e)) => Err(e),
564 }
565 };
566
567 match result {
568 Ok(Some((key, data))) => {
569 if key.starts_with(&self.prefix) {
570 match (KC::bytes_decode(key), DC::bytes_decode(data)) {
571 (Ok(key), Ok(data)) => Some(Ok((key, data))),
572 (Err(e), _) | (_, Err(e)) => Some(Err(Error::Decoding(e))),
573 }
574 } else {
575 None
576 }
577 }
578 Ok(None) => None,
579 Err(e) => Some(Err(e)),
580 }
581 }
582}
583
584impl<KC, DC, C, IM> fmt::Debug for RoRevPrefix<'_, KC, DC, C, IM> {
585 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
586 f.debug_struct("RoRevPrefix").finish()
587 }
588}
589
590pub struct RwRevPrefix<'txn, KC, DC, C = DefaultComparator, IM = MoveThroughDuplicateValues> {
592 cursor: RwCursor<'txn>,
593 prefix: Vec<u8>,
594 move_on_last: bool,
595 _phantom: marker::PhantomData<(KC, DC, C, IM)>,
596}
597
598impl<'txn, KC, DC, C, IM> RwRevPrefix<'txn, KC, DC, C, IM> {
599 pub(crate) fn new(cursor: RwCursor<'txn>, prefix: Vec<u8>) -> RwRevPrefix<'txn, KC, DC, C, IM> {
600 RwRevPrefix { cursor, prefix, move_on_last: true, _phantom: marker::PhantomData }
601 }
602
603 pub unsafe fn del_current(&mut self) -> Result<bool> {
617 self.cursor.del_current()
618 }
619
620 pub unsafe fn put_current<'a>(
644 &mut self,
645 key: &'a KC::EItem,
646 data: &'a DC::EItem,
647 ) -> Result<bool>
648 where
649 KC: BytesEncode<'a>,
650 DC: BytesEncode<'a>,
651 {
652 let key_bytes: Cow<[u8]> = KC::bytes_encode(key).map_err(Error::Encoding)?;
653 let data_bytes: Cow<[u8]> = DC::bytes_encode(data).map_err(Error::Encoding)?;
654 self.cursor.put_current(&key_bytes, &data_bytes)
655 }
656
657 pub unsafe fn put_current_reserved_with_flags<'a, F>(
671 &mut self,
672 flags: PutFlags,
673 key: &'a KC::EItem,
674 data_size: usize,
675 write_func: F,
676 ) -> Result<bool>
677 where
678 KC: BytesEncode<'a>,
679 F: FnOnce(&mut ReservedSpace) -> io::Result<()>,
680 {
681 let key_bytes: Cow<[u8]> = KC::bytes_encode(key).map_err(Error::Encoding)?;
682 self.cursor.put_current_reserved_with_flags(flags, &key_bytes, data_size, write_func)
683 }
684
685 pub unsafe fn put_current_with_options<'a, NDC>(
703 &mut self,
704 flags: PutFlags,
705 key: &'a KC::EItem,
706 data: &'a NDC::EItem,
707 ) -> Result<()>
708 where
709 KC: BytesEncode<'a>,
710 NDC: BytesEncode<'a>,
711 {
712 let key_bytes: Cow<[u8]> = KC::bytes_encode(key).map_err(Error::Encoding)?;
713 let data_bytes: Cow<[u8]> = NDC::bytes_encode(data).map_err(Error::Encoding)?;
714 self.cursor.put_current_with_flags(flags, &key_bytes, &data_bytes)
715 }
716
717 pub fn move_between_keys(self) -> RwRevPrefix<'txn, KC, DC, C, MoveBetweenKeys> {
721 RwRevPrefix {
722 cursor: self.cursor,
723 prefix: self.prefix,
724 move_on_last: self.move_on_last,
725 _phantom: marker::PhantomData,
726 }
727 }
728
729 pub fn move_through_duplicate_values(
733 self,
734 ) -> RwRevPrefix<'txn, KC, DC, C, MoveThroughDuplicateValues> {
735 RwRevPrefix {
736 cursor: self.cursor,
737 prefix: self.prefix,
738 move_on_last: self.move_on_last,
739 _phantom: marker::PhantomData,
740 }
741 }
742
743 pub fn remap_types<KC2, DC2>(self) -> RwRevPrefix<'txn, KC2, DC2, C, IM> {
745 RwRevPrefix {
746 cursor: self.cursor,
747 prefix: self.prefix,
748 move_on_last: self.move_on_last,
749 _phantom: marker::PhantomData,
750 }
751 }
752
753 pub fn remap_key_type<KC2>(self) -> RwRevPrefix<'txn, KC2, DC, C, IM> {
755 self.remap_types::<KC2, DC>()
756 }
757
758 pub fn remap_data_type<DC2>(self) -> RwRevPrefix<'txn, KC, DC2, C, IM> {
760 self.remap_types::<KC, DC2>()
761 }
762
763 pub fn lazily_decode_data(self) -> RwRevPrefix<'txn, KC, LazyDecode<DC>, C, IM> {
765 self.remap_types::<KC, LazyDecode<DC>>()
766 }
767}
768
769impl<'txn, KC, DC, C, IM> Iterator for RwRevPrefix<'txn, KC, DC, C, IM>
770where
771 KC: BytesDecode<'txn>,
772 DC: BytesDecode<'txn>,
773 C: LexicographicComparator,
774 IM: IterationMethod,
775{
776 type Item = Result<(KC::DItem, DC::DItem)>;
777
778 fn next(&mut self) -> Option<Self::Item> {
779 let result = if self.move_on_last {
780 self.move_on_last = false;
781 move_on_prefix_end::<C>(&mut self.cursor, &mut self.prefix)
782 } else {
783 self.cursor.move_on_prev(IM::MOVE_OPERATION)
784 };
785
786 match result {
787 Ok(Some((key, data))) => {
788 if key.starts_with(&self.prefix) {
789 match (KC::bytes_decode(key), DC::bytes_decode(data)) {
790 (Ok(key), Ok(data)) => Some(Ok((key, data))),
791 (Err(e), _) | (_, Err(e)) => Some(Err(Error::Decoding(e))),
792 }
793 } else {
794 None
795 }
796 }
797 Ok(None) => None,
798 Err(e) => Some(Err(e)),
799 }
800 }
801
802 fn last(mut self) -> Option<Self::Item> {
803 let result = if self.move_on_last {
804 self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix)
805 } else {
806 let current = self.cursor.current();
807 let start = self.cursor.move_on_key_greater_than_or_equal_to(&self.prefix);
808 match (current, start) {
809 (Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => {
810 Ok(Some((key, data)))
811 }
812 (Ok(_), Ok(_)) => Ok(None),
813 (Err(e), _) | (_, Err(e)) => Err(e),
814 }
815 };
816
817 match result {
818 Ok(Some((key, data))) => {
819 if key.starts_with(&self.prefix) {
820 match (KC::bytes_decode(key), DC::bytes_decode(data)) {
821 (Ok(key), Ok(data)) => Some(Ok((key, data))),
822 (Err(e), _) | (_, Err(e)) => Some(Err(Error::Decoding(e))),
823 }
824 } else {
825 None
826 }
827 }
828 Ok(None) => None,
829 Err(e) => Some(Err(e)),
830 }
831 }
832}
833
834impl<KC, DC, C, IM> fmt::Debug for RwRevPrefix<'_, KC, DC, C, IM> {
835 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
836 f.debug_struct("RwRevPrefix").finish()
837 }
838}