inspect_format/
block_index.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::constants;
6use std::fmt;
7use std::ops::{Add, AddAssign, BitXor, Deref, Sub, SubAssign};
8
9#[derive(Debug, Copy, Clone, Ord, PartialOrd, PartialEq, Eq, Hash)]
10pub struct BlockIndex(u32);
11
12impl BlockIndex {
13    pub const ROOT: Self = Self::new(0);
14    pub const HEADER: Self = Self::new(0);
15    pub const EMPTY: Self = Self::new(0);
16
17    pub const fn new(idx: u32) -> Self {
18        Self(idx)
19    }
20
21    /// Get index in the VMO for a given |offset|.
22    pub fn from_offset(offset: usize) -> BlockIndex {
23        // Safety: `offset` can't be larger than the largest `BlockIndex`
24        Self::new(u32::try_from(offset / constants::MIN_ORDER_SIZE).unwrap())
25    }
26
27    /// Get offset in the VMO for |self|.
28    pub fn offset(&self) -> usize {
29        usize::from(self) * constants::MIN_ORDER_SIZE
30    }
31}
32
33impl From<u32> for BlockIndex {
34    fn from(idx: u32) -> BlockIndex {
35        BlockIndex::new(idx)
36    }
37}
38
39impl From<&u32> for BlockIndex {
40    fn from(idx: &u32) -> BlockIndex {
41        BlockIndex::new(*idx)
42    }
43}
44
45impl Deref for BlockIndex {
46    type Target = u32;
47
48    fn deref(&self) -> &Self::Target {
49        &self.0
50    }
51}
52
53// Panics if a u32 is larger than a usize
54impl From<BlockIndex> for usize {
55    fn from(idx: BlockIndex) -> usize {
56        // usize on Fuchsia is 64 bits
57        *idx as usize
58    }
59}
60
61// Panics if a u32 is larger than a usize
62impl From<&BlockIndex> for usize {
63    fn from(idx: &BlockIndex) -> usize {
64        // usize on Fuchsia is 64 bits
65        **idx as usize
66    }
67}
68
69impl fmt::Display for BlockIndex {
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        write!(f, "{}", self.0)
72    }
73}
74
75// Basically pointer arithmetic for BlockIndex, which is somewhat sad
76// but pretty useful conceptually
77impl Add<u32> for BlockIndex {
78    type Output = Self;
79
80    fn add(self, other: u32) -> Self {
81        BlockIndex::new(self.0 + other)
82    }
83}
84
85impl AddAssign<u32> for BlockIndex {
86    fn add_assign(&mut self, other: u32) {
87        self.0 += other
88    }
89}
90
91impl Sub<u32> for BlockIndex {
92    type Output = Self;
93
94    fn sub(self, other: u32) -> Self {
95        BlockIndex::new(self.0 - other)
96    }
97}
98
99impl SubAssign<u32> for BlockIndex {
100    fn sub_assign(&mut self, other: u32) {
101        self.0 -= other
102    }
103}
104
105impl Add for BlockIndex {
106    type Output = Self;
107
108    fn add(self, other: Self) -> Self {
109        BlockIndex::new(self.0 + other.0)
110    }
111}
112
113impl AddAssign for BlockIndex {
114    fn add_assign(&mut self, other: Self) {
115        self.0 += other.0
116    }
117}
118
119impl Sub for BlockIndex {
120    type Output = Self;
121
122    fn sub(self, other: Self) -> Self {
123        BlockIndex::new(self.0 - other.0)
124    }
125}
126
127impl SubAssign for BlockIndex {
128    fn sub_assign(&mut self, other: Self) {
129        self.0 -= other.0
130    }
131}
132
133impl BitXor for BlockIndex {
134    type Output = Self;
135
136    fn bitxor(self, rhs: Self) -> Self::Output {
137        Self(self.0 ^ rhs.0)
138    }
139}