test_bd/
position.rs

1use std::fmt;
2use std::ops::AddAssign;
3use std::ops::Sub;
4
5use serde::Deserialize;
6use serde::Serialize;
7
8/// A position index representing an 8-byte aligned offset in a block device.
9///
10/// `IndexPos` is a type-safe wrapper around a `u64` that represents positions
11/// in units of 8 bytes. This is used throughout the library to ensure proper
12/// alignment and avoid confusion between byte offsets and index positions.
13///
14/// # Examples
15///
16/// ```
17/// use test_bd::IndexPos;
18///
19/// // Create a position at index 100 (which is byte offset 800)
20/// let pos = IndexPos::new(100);
21/// assert_eq!(pos.as_u64(), 100);
22/// assert_eq!(pos.as_abs_byte_offset(), 800);
23/// ```
24#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
25#[repr(transparent)]
26pub struct IndexPos(u64);
27
28impl IndexPos {
29    /// Creates a new `IndexPos` from an index value.
30    ///
31    /// # Arguments
32    ///
33    /// * `idx` - The index value (in units of 8 bytes)
34    ///
35    /// # Examples
36    ///
37    /// ```
38    /// use test_bd::IndexPos;
39    ///
40    /// let pos = IndexPos::new(42);
41    /// assert_eq!(pos.as_u64(), 42);
42    /// ```
43    pub const fn new(idx: u64) -> Self {
44        IndexPos(idx)
45    }
46
47    /// Returns the raw index value as a `u64`.
48    ///
49    /// # Examples
50    ///
51    /// ```
52    /// use test_bd::IndexPos;
53    ///
54    /// let pos = IndexPos::new(100);
55    /// assert_eq!(pos.as_u64(), 100);
56    /// ```
57    pub const fn as_u64(self) -> u64 {
58        self.0
59    }
60
61    /// Converts the index position to an absolute byte offset.
62    ///
63    /// Since each index represents 8 bytes, this returns `index * 8`.
64    /// However, this could change, so use this method.
65    ///
66    /// # Examples
67    ///
68    /// ```
69    /// use test_bd::IndexPos;
70    ///
71    /// let pos = IndexPos::new(100);
72    /// assert_eq!(pos.as_abs_byte_offset(), 800);
73    /// ```
74    pub const fn as_abs_byte_offset(self) -> u64 {
75        self.0 * 8
76    }
77}
78
79impl fmt::Display for IndexPos {
80    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81        write!(f, "IndexPos({})", self.0)
82    }
83}
84
85impl AddAssign for IndexPos {
86    fn add_assign(&mut self, other: Self) {
87        self.0 += other.0;
88    }
89}
90
91impl Sub for IndexPos {
92    type Output = u64;
93
94    fn sub(self, rhs: IndexPos) -> Self::Output {
95        self.0 - rhs.0
96    }
97}