sequence_numbers.rs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. //! Sequence numbers.
  2. use duplicate::duplicate_item;
  3. /// Exhausted the available sequence numbers.
  4. #[derive(Clone, Debug, thiserror::Error)]
  5. #[error("Sequence number would overflow")]
  6. pub struct SequenceNumberOverflow;
  7. /// A sequence number value, safely yielded by calling [`SequenceNumberU32::get_and_increment`] resp.
  8. /// [`SequenceNumberU64::get_and_increment`].
  9. pub(crate) struct SequenceNumberValue<T>(pub(crate) T);
  10. /// A generic 64-bit unsigned sequence number. Prevents wrapping.
  11. #[duplicate_item(
  12. struct_name value_type;
  13. [ SequenceNumberU32 ] [ u32 ];
  14. [ SequenceNumberU64 ] [ u64 ];
  15. )]
  16. #[derive(Debug)]
  17. pub(crate) struct struct_name {
  18. value: value_type,
  19. }
  20. /// A generic 64-bit unsigned sequence number. Prevents wrapping.
  21. #[duplicate_item(
  22. struct_name value_type;
  23. [ SequenceNumberU32 ] [ u32 ];
  24. [ SequenceNumberU64 ] [ u64 ];
  25. )]
  26. #[expect(clippy::allow_attributes, reason = "duplicate shenanigans")]
  27. impl struct_name {
  28. /// Create a new sequence number starting with `start`.
  29. #[allow(dead_code, reason = "Will use later")]
  30. pub(crate) fn new(start: value_type) -> Self {
  31. Self { value: start }
  32. }
  33. /// Return the next sequence number (i.e. the current value plus one). Increases the internal
  34. /// value by one.
  35. ///
  36. /// # Errors
  37. ///
  38. /// Return a [`SequenceNumberOverflow`] if the increment would result in an overflow.
  39. pub(crate) fn get_and_increment(
  40. &mut self,
  41. ) -> Result<SequenceNumberValue<value_type>, SequenceNumberOverflow> {
  42. let next = self.value;
  43. self.value = self.value.checked_add(1).ok_or(SequenceNumberOverflow)?;
  44. Ok(SequenceNumberValue(next))
  45. }
  46. }