xref: /aosp_15_r20/external/crosvm/resources/src/address_range.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::cmp;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::ops::RangeInclusive;
7*bb4ee6a4SAndroid Build Coastguard Worker 
8*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize;
9*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize;
10*bb4ee6a4SAndroid Build Coastguard Worker 
11*bb4ee6a4SAndroid Build Coastguard Worker /// Represents a range of addresses from `start` to `end`, inclusive.
12*bb4ee6a4SAndroid Build Coastguard Worker ///
13*bb4ee6a4SAndroid Build Coastguard Worker /// Why not use the standard `RangeInclusive`? `RangeInclusive` is not `Copy`, because it tries to
14*bb4ee6a4SAndroid Build Coastguard Worker /// be an iterator as well as a range (which also means it is larger than necessary). Additionally,
15*bb4ee6a4SAndroid Build Coastguard Worker /// we would also like to implement some convenience functions for our own type.
16*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Deserialize, Serialize)]
17*bb4ee6a4SAndroid Build Coastguard Worker #[serde(deny_unknown_fields)]
18*bb4ee6a4SAndroid Build Coastguard Worker pub struct AddressRange {
19*bb4ee6a4SAndroid Build Coastguard Worker     pub start: u64,
20*bb4ee6a4SAndroid Build Coastguard Worker     pub end: u64,
21*bb4ee6a4SAndroid Build Coastguard Worker }
22*bb4ee6a4SAndroid Build Coastguard Worker 
23*bb4ee6a4SAndroid Build Coastguard Worker impl AddressRange {
24*bb4ee6a4SAndroid Build Coastguard Worker     /// Creates a new `AddressRange` from `start` and `end` (inclusive) addresses.
from_start_and_end(start: u64, end: u64) -> Self25*bb4ee6a4SAndroid Build Coastguard Worker     pub const fn from_start_and_end(start: u64, end: u64) -> Self {
26*bb4ee6a4SAndroid Build Coastguard Worker         AddressRange { start, end }
27*bb4ee6a4SAndroid Build Coastguard Worker     }
28*bb4ee6a4SAndroid Build Coastguard Worker 
29*bb4ee6a4SAndroid Build Coastguard Worker     /// Creates a new `AddressRange` from `start` extending `size` bytes.
30*bb4ee6a4SAndroid Build Coastguard Worker     ///
31*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns `None` if the generated range is not representable as an `AddressRange`.
from_start_and_size(start: u64, size: u64) -> Option<Self>32*bb4ee6a4SAndroid Build Coastguard Worker     pub const fn from_start_and_size(start: u64, size: u64) -> Option<Self> {
33*bb4ee6a4SAndroid Build Coastguard Worker         if size == 0 {
34*bb4ee6a4SAndroid Build Coastguard Worker             Some(AddressRange::empty())
35*bb4ee6a4SAndroid Build Coastguard Worker         } else if let Some(end) = start.checked_add(size - 1) {
36*bb4ee6a4SAndroid Build Coastguard Worker             Some(AddressRange { start, end })
37*bb4ee6a4SAndroid Build Coastguard Worker         } else {
38*bb4ee6a4SAndroid Build Coastguard Worker             None
39*bb4ee6a4SAndroid Build Coastguard Worker         }
40*bb4ee6a4SAndroid Build Coastguard Worker     }
41*bb4ee6a4SAndroid Build Coastguard Worker 
42*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns an empty range.
empty() -> Self43*bb4ee6a4SAndroid Build Coastguard Worker     pub const fn empty() -> Self {
44*bb4ee6a4SAndroid Build Coastguard Worker         AddressRange { start: 1, end: 0 }
45*bb4ee6a4SAndroid Build Coastguard Worker     }
46*bb4ee6a4SAndroid Build Coastguard Worker 
47*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns `true` if this range is empty (contains no addresses).
is_empty(&self) -> bool48*bb4ee6a4SAndroid Build Coastguard Worker     pub fn is_empty(&self) -> bool {
49*bb4ee6a4SAndroid Build Coastguard Worker         self.end < self.start
50*bb4ee6a4SAndroid Build Coastguard Worker     }
51*bb4ee6a4SAndroid Build Coastguard Worker 
52*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns `true` if this range contains `address`.
contains(&self, address: u64) -> bool53*bb4ee6a4SAndroid Build Coastguard Worker     pub fn contains(&self, address: u64) -> bool {
54*bb4ee6a4SAndroid Build Coastguard Worker         address >= self.start && address <= self.end
55*bb4ee6a4SAndroid Build Coastguard Worker     }
56*bb4ee6a4SAndroid Build Coastguard Worker 
57*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns `true` if `other` is fully contained within this range.
58*bb4ee6a4SAndroid Build Coastguard Worker     ///
59*bb4ee6a4SAndroid Build Coastguard Worker     /// Empty ranges are considered to be not contained by any range.
contains_range(&self, other: AddressRange) -> bool60*bb4ee6a4SAndroid Build Coastguard Worker     pub fn contains_range(&self, other: AddressRange) -> bool {
61*bb4ee6a4SAndroid Build Coastguard Worker         !other.is_empty() && other.start >= self.start && other.end <= self.end
62*bb4ee6a4SAndroid Build Coastguard Worker     }
63*bb4ee6a4SAndroid Build Coastguard Worker 
64*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns `true` if the two ranges have any addresses in common.
overlaps(&self, other: AddressRange) -> bool65*bb4ee6a4SAndroid Build Coastguard Worker     pub fn overlaps(&self, other: AddressRange) -> bool {
66*bb4ee6a4SAndroid Build Coastguard Worker         !self.intersect(other).is_empty()
67*bb4ee6a4SAndroid Build Coastguard Worker     }
68*bb4ee6a4SAndroid Build Coastguard Worker 
69*bb4ee6a4SAndroid Build Coastguard Worker     /// Find the intersection (overlapping region) of two ranges.
70*bb4ee6a4SAndroid Build Coastguard Worker     ///
71*bb4ee6a4SAndroid Build Coastguard Worker     /// If there is no intersection, the resulting `AddressRange` will be empty.
intersect(&self, other: AddressRange) -> AddressRange72*bb4ee6a4SAndroid Build Coastguard Worker     pub fn intersect(&self, other: AddressRange) -> AddressRange {
73*bb4ee6a4SAndroid Build Coastguard Worker         let start = cmp::max(self.start, other.start);
74*bb4ee6a4SAndroid Build Coastguard Worker         let end = cmp::min(self.end, other.end);
75*bb4ee6a4SAndroid Build Coastguard Worker         AddressRange { start, end }
76*bb4ee6a4SAndroid Build Coastguard Worker     }
77*bb4ee6a4SAndroid Build Coastguard Worker 
78*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns the ranges of addresses contained in `self` but not in `other`.
79*bb4ee6a4SAndroid Build Coastguard Worker     ///
80*bb4ee6a4SAndroid Build Coastguard Worker     /// The first returned range will contain the addresses in `self` that are less than the start
81*bb4ee6a4SAndroid Build Coastguard Worker     /// of `other`, which will be empty if the starts of the ranges coincide.
82*bb4ee6a4SAndroid Build Coastguard Worker     ///
83*bb4ee6a4SAndroid Build Coastguard Worker     /// The second returned range will contain the addresses in `self` that are greater than the end
84*bb4ee6a4SAndroid Build Coastguard Worker     /// of `other`, which will be empty if the ends of the ranges coincide.
non_overlapping_ranges(&self, other: AddressRange) -> (AddressRange, AddressRange)85*bb4ee6a4SAndroid Build Coastguard Worker     pub fn non_overlapping_ranges(&self, other: AddressRange) -> (AddressRange, AddressRange) {
86*bb4ee6a4SAndroid Build Coastguard Worker         let before = if self.start >= other.start {
87*bb4ee6a4SAndroid Build Coastguard Worker             Self::empty()
88*bb4ee6a4SAndroid Build Coastguard Worker         } else {
89*bb4ee6a4SAndroid Build Coastguard Worker             let start = cmp::min(self.start, other.start);
90*bb4ee6a4SAndroid Build Coastguard Worker 
91*bb4ee6a4SAndroid Build Coastguard Worker             // We know that self.start != other.start, so the maximum of the two cannot be 0, so it
92*bb4ee6a4SAndroid Build Coastguard Worker             // is safe to subtract 1.
93*bb4ee6a4SAndroid Build Coastguard Worker             let end = cmp::max(self.start, other.start) - 1;
94*bb4ee6a4SAndroid Build Coastguard Worker 
95*bb4ee6a4SAndroid Build Coastguard Worker             // For non-overlapping ranges, don't allow end to extend past self.end.
96*bb4ee6a4SAndroid Build Coastguard Worker             let end = cmp::min(end, self.end);
97*bb4ee6a4SAndroid Build Coastguard Worker 
98*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start, end }
99*bb4ee6a4SAndroid Build Coastguard Worker         };
100*bb4ee6a4SAndroid Build Coastguard Worker 
101*bb4ee6a4SAndroid Build Coastguard Worker         let after = if self.end <= other.end {
102*bb4ee6a4SAndroid Build Coastguard Worker             Self::empty()
103*bb4ee6a4SAndroid Build Coastguard Worker         } else {
104*bb4ee6a4SAndroid Build Coastguard Worker             // We know that self.end != other.end, so the minimum of the two cannot be `u64::MAX`,
105*bb4ee6a4SAndroid Build Coastguard Worker             // so it is safe to add 1.
106*bb4ee6a4SAndroid Build Coastguard Worker             let start = cmp::min(self.end, other.end) + 1;
107*bb4ee6a4SAndroid Build Coastguard Worker 
108*bb4ee6a4SAndroid Build Coastguard Worker             // For non-overlapping ranges, don't allow start to extend before self.start.
109*bb4ee6a4SAndroid Build Coastguard Worker             let start = cmp::max(start, self.start);
110*bb4ee6a4SAndroid Build Coastguard Worker 
111*bb4ee6a4SAndroid Build Coastguard Worker             let end = cmp::max(self.end, other.end);
112*bb4ee6a4SAndroid Build Coastguard Worker 
113*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start, end }
114*bb4ee6a4SAndroid Build Coastguard Worker         };
115*bb4ee6a4SAndroid Build Coastguard Worker 
116*bb4ee6a4SAndroid Build Coastguard Worker         (before, after)
117*bb4ee6a4SAndroid Build Coastguard Worker     }
118*bb4ee6a4SAndroid Build Coastguard Worker 
119*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns the two subsets of this range split at the `split_start` address.
120*bb4ee6a4SAndroid Build Coastguard Worker     ///
121*bb4ee6a4SAndroid Build Coastguard Worker     /// If `split_start` is not contained in this range, returns the original range and an empty
122*bb4ee6a4SAndroid Build Coastguard Worker     /// range.
split_at(&self, split_start: u64) -> (AddressRange, AddressRange)123*bb4ee6a4SAndroid Build Coastguard Worker     pub fn split_at(&self, split_start: u64) -> (AddressRange, AddressRange) {
124*bb4ee6a4SAndroid Build Coastguard Worker         // split_start == self.start is handled as a special case so we know that split_start - 1 is
125*bb4ee6a4SAndroid Build Coastguard Worker         // safe below (and so the empty range is always returned second if present).
126*bb4ee6a4SAndroid Build Coastguard Worker         if split_start <= self.start || split_start > self.end {
127*bb4ee6a4SAndroid Build Coastguard Worker             (*self, Self::empty())
128*bb4ee6a4SAndroid Build Coastguard Worker         } else {
129*bb4ee6a4SAndroid Build Coastguard Worker             (
130*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange {
131*bb4ee6a4SAndroid Build Coastguard Worker                     start: self.start,
132*bb4ee6a4SAndroid Build Coastguard Worker                     end: split_start - 1,
133*bb4ee6a4SAndroid Build Coastguard Worker                 },
134*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange {
135*bb4ee6a4SAndroid Build Coastguard Worker                     start: split_start,
136*bb4ee6a4SAndroid Build Coastguard Worker                     end: self.end,
137*bb4ee6a4SAndroid Build Coastguard Worker                 },
138*bb4ee6a4SAndroid Build Coastguard Worker             )
139*bb4ee6a4SAndroid Build Coastguard Worker         }
140*bb4ee6a4SAndroid Build Coastguard Worker     }
141*bb4ee6a4SAndroid Build Coastguard Worker 
142*bb4ee6a4SAndroid Build Coastguard Worker     /// Computes the length of an `AddressRange`.
143*bb4ee6a4SAndroid Build Coastguard Worker     ///
144*bb4ee6a4SAndroid Build Coastguard Worker     /// Returns `None` if the length cannot be represented in `u64` (if the range is
145*bb4ee6a4SAndroid Build Coastguard Worker     /// `0..=u64::MAX`).
len(&self) -> Option<u64>146*bb4ee6a4SAndroid Build Coastguard Worker     pub fn len(&self) -> Option<u64> {
147*bb4ee6a4SAndroid Build Coastguard Worker         // Treat any range we consider "empty" (end < start) as having 0 length.
148*bb4ee6a4SAndroid Build Coastguard Worker         if self.is_empty() {
149*bb4ee6a4SAndroid Build Coastguard Worker             Some(0)
150*bb4ee6a4SAndroid Build Coastguard Worker         } else {
151*bb4ee6a4SAndroid Build Coastguard Worker             (self.end - self.start).checked_add(1)
152*bb4ee6a4SAndroid Build Coastguard Worker         }
153*bb4ee6a4SAndroid Build Coastguard Worker     }
154*bb4ee6a4SAndroid Build Coastguard Worker 
log(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result155*bb4ee6a4SAndroid Build Coastguard Worker     fn log(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
156*bb4ee6a4SAndroid Build Coastguard Worker         if self.is_empty() {
157*bb4ee6a4SAndroid Build Coastguard Worker             f.write_str("empty")
158*bb4ee6a4SAndroid Build Coastguard Worker         } else {
159*bb4ee6a4SAndroid Build Coastguard Worker             f.write_fmt(format_args!("{:#x}..={:#x}", self.start, self.end))
160*bb4ee6a4SAndroid Build Coastguard Worker         }
161*bb4ee6a4SAndroid Build Coastguard Worker     }
162*bb4ee6a4SAndroid Build Coastguard Worker }
163*bb4ee6a4SAndroid Build Coastguard Worker 
164*bb4ee6a4SAndroid Build Coastguard Worker impl std::fmt::Display for AddressRange {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result165*bb4ee6a4SAndroid Build Coastguard Worker     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
166*bb4ee6a4SAndroid Build Coastguard Worker         self.log(f)
167*bb4ee6a4SAndroid Build Coastguard Worker     }
168*bb4ee6a4SAndroid Build Coastguard Worker }
169*bb4ee6a4SAndroid Build Coastguard Worker 
170*bb4ee6a4SAndroid Build Coastguard Worker impl std::fmt::Debug for AddressRange {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result171*bb4ee6a4SAndroid Build Coastguard Worker     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
172*bb4ee6a4SAndroid Build Coastguard Worker         self.log(f)
173*bb4ee6a4SAndroid Build Coastguard Worker     }
174*bb4ee6a4SAndroid Build Coastguard Worker }
175*bb4ee6a4SAndroid Build Coastguard Worker 
176*bb4ee6a4SAndroid Build Coastguard Worker impl From<RangeInclusive<u64>> for AddressRange {
from(range: RangeInclusive<u64>) -> AddressRange177*bb4ee6a4SAndroid Build Coastguard Worker     fn from(range: RangeInclusive<u64>) -> AddressRange {
178*bb4ee6a4SAndroid Build Coastguard Worker         AddressRange {
179*bb4ee6a4SAndroid Build Coastguard Worker             start: *range.start(),
180*bb4ee6a4SAndroid Build Coastguard Worker             end: *range.end(),
181*bb4ee6a4SAndroid Build Coastguard Worker         }
182*bb4ee6a4SAndroid Build Coastguard Worker     }
183*bb4ee6a4SAndroid Build Coastguard Worker }
184*bb4ee6a4SAndroid Build Coastguard Worker 
185*bb4ee6a4SAndroid Build Coastguard Worker impl From<AddressRange> for RangeInclusive<u64> {
from(address_range: AddressRange) -> RangeInclusive<u64>186*bb4ee6a4SAndroid Build Coastguard Worker     fn from(address_range: AddressRange) -> RangeInclusive<u64> {
187*bb4ee6a4SAndroid Build Coastguard Worker         address_range.start..=address_range.end
188*bb4ee6a4SAndroid Build Coastguard Worker     }
189*bb4ee6a4SAndroid Build Coastguard Worker }
190*bb4ee6a4SAndroid Build Coastguard Worker 
191*bb4ee6a4SAndroid Build Coastguard Worker /// Custom comparison function that provides a total order over all possible `AddressRange` values
192*bb4ee6a4SAndroid Build Coastguard Worker /// and considers all empty ranges to be equal.
193*bb4ee6a4SAndroid Build Coastguard Worker impl cmp::Ord for AddressRange {
cmp(&self, other: &Self) -> cmp::Ordering194*bb4ee6a4SAndroid Build Coastguard Worker     fn cmp(&self, other: &Self) -> cmp::Ordering {
195*bb4ee6a4SAndroid Build Coastguard Worker         match (self.is_empty(), other.is_empty()) {
196*bb4ee6a4SAndroid Build Coastguard Worker             // Any empty range is equal to any other empty range.
197*bb4ee6a4SAndroid Build Coastguard Worker             (true, true) => cmp::Ordering::Equal,
198*bb4ee6a4SAndroid Build Coastguard Worker             // An empty range is less than any non-empty range.
199*bb4ee6a4SAndroid Build Coastguard Worker             (true, false) => cmp::Ordering::Less,
200*bb4ee6a4SAndroid Build Coastguard Worker             // Any non-empty range is greater than an empty range.
201*bb4ee6a4SAndroid Build Coastguard Worker             (false, true) => cmp::Ordering::Greater,
202*bb4ee6a4SAndroid Build Coastguard Worker             // Two non-empty ranges are ordered based on `start`, and if those are equal, `end`.
203*bb4ee6a4SAndroid Build Coastguard Worker             (false, false) => self
204*bb4ee6a4SAndroid Build Coastguard Worker                 .start
205*bb4ee6a4SAndroid Build Coastguard Worker                 .cmp(&other.start)
206*bb4ee6a4SAndroid Build Coastguard Worker                 .then_with(|| self.end.cmp(&other.end)),
207*bb4ee6a4SAndroid Build Coastguard Worker         }
208*bb4ee6a4SAndroid Build Coastguard Worker     }
209*bb4ee6a4SAndroid Build Coastguard Worker }
210*bb4ee6a4SAndroid Build Coastguard Worker 
211*bb4ee6a4SAndroid Build Coastguard Worker impl cmp::PartialOrd for AddressRange {
partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>212*bb4ee6a4SAndroid Build Coastguard Worker     fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
213*bb4ee6a4SAndroid Build Coastguard Worker         Some(cmp::Ord::cmp(self, other))
214*bb4ee6a4SAndroid Build Coastguard Worker     }
215*bb4ee6a4SAndroid Build Coastguard Worker }
216*bb4ee6a4SAndroid Build Coastguard Worker 
217*bb4ee6a4SAndroid Build Coastguard Worker impl cmp::PartialEq for AddressRange {
eq(&self, other: &Self) -> bool218*bb4ee6a4SAndroid Build Coastguard Worker     fn eq(&self, other: &Self) -> bool {
219*bb4ee6a4SAndroid Build Coastguard Worker         cmp::Ord::cmp(self, other) == cmp::Ordering::Equal
220*bb4ee6a4SAndroid Build Coastguard Worker     }
221*bb4ee6a4SAndroid Build Coastguard Worker }
222*bb4ee6a4SAndroid Build Coastguard Worker 
223*bb4ee6a4SAndroid Build Coastguard Worker // The `PartialEq` implementation is reflexive, symmetric, and transitive.
224*bb4ee6a4SAndroid Build Coastguard Worker impl cmp::Eq for AddressRange {}
225*bb4ee6a4SAndroid Build Coastguard Worker 
226*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
227*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
228*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
229*bb4ee6a4SAndroid Build Coastguard Worker 
230*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
is_empty()231*bb4ee6a4SAndroid Build Coastguard Worker     fn is_empty() {
232*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange { start: 1, end: 0 }.is_empty());
233*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange {
234*bb4ee6a4SAndroid Build Coastguard Worker             start: u64::MAX,
235*bb4ee6a4SAndroid Build Coastguard Worker             end: 0
236*bb4ee6a4SAndroid Build Coastguard Worker         }
237*bb4ee6a4SAndroid Build Coastguard Worker         .is_empty());
238*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange {
239*bb4ee6a4SAndroid Build Coastguard Worker             start: u64::MAX,
240*bb4ee6a4SAndroid Build Coastguard Worker             end: u64::MAX - 1
241*bb4ee6a4SAndroid Build Coastguard Worker         }
242*bb4ee6a4SAndroid Build Coastguard Worker         .is_empty());
243*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange::empty().is_empty());
244*bb4ee6a4SAndroid Build Coastguard Worker 
245*bb4ee6a4SAndroid Build Coastguard Worker         assert!(!AddressRange { start: 0, end: 1 }.is_empty());
246*bb4ee6a4SAndroid Build Coastguard Worker         assert!(!AddressRange { start: 1, end: 1 }.is_empty());
247*bb4ee6a4SAndroid Build Coastguard Worker     }
248*bb4ee6a4SAndroid Build Coastguard Worker 
249*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
contains()250*bb4ee6a4SAndroid Build Coastguard Worker     fn contains() {
251*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange { start: 0, end: 5 }.contains(3));
252*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange { start: 0, end: 0 }.contains(0));
253*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange {
254*bb4ee6a4SAndroid Build Coastguard Worker             start: 0,
255*bb4ee6a4SAndroid Build Coastguard Worker             end: u64::MAX
256*bb4ee6a4SAndroid Build Coastguard Worker         }
257*bb4ee6a4SAndroid Build Coastguard Worker         .contains(u64::MAX));
258*bb4ee6a4SAndroid Build Coastguard Worker 
259*bb4ee6a4SAndroid Build Coastguard Worker         // Empty ranges do not contain any addresses
260*bb4ee6a4SAndroid Build Coastguard Worker         assert!(!AddressRange { start: 5, end: 0 }.contains(3));
261*bb4ee6a4SAndroid Build Coastguard Worker     }
262*bb4ee6a4SAndroid Build Coastguard Worker 
263*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
contains_range()264*bb4ee6a4SAndroid Build Coastguard Worker     fn contains_range() {
265*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 0, end: 5 }));
266*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 1, end: 3 }));
267*bb4ee6a4SAndroid Build Coastguard Worker 
268*bb4ee6a4SAndroid Build Coastguard Worker         // Partly overlapping ranges
269*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
270*bb4ee6a4SAndroid Build Coastguard Worker             !AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 3, end: 9 })
271*bb4ee6a4SAndroid Build Coastguard Worker         );
272*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
273*bb4ee6a4SAndroid Build Coastguard Worker             !AddressRange { start: 3, end: 9 }.contains_range(AddressRange { start: 0, end: 5 })
274*bb4ee6a4SAndroid Build Coastguard Worker         );
275*bb4ee6a4SAndroid Build Coastguard Worker 
276*bb4ee6a4SAndroid Build Coastguard Worker         // Completely discontiguous ranges
277*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
278*bb4ee6a4SAndroid Build Coastguard Worker             !AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 6, end: 9 })
279*bb4ee6a4SAndroid Build Coastguard Worker         );
280*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
281*bb4ee6a4SAndroid Build Coastguard Worker             !AddressRange { start: 6, end: 9 }.contains_range(AddressRange { start: 0, end: 5 })
282*bb4ee6a4SAndroid Build Coastguard Worker         );
283*bb4ee6a4SAndroid Build Coastguard Worker 
284*bb4ee6a4SAndroid Build Coastguard Worker         // Empty ranges do not contain anything
285*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
286*bb4ee6a4SAndroid Build Coastguard Worker             !AddressRange { start: 5, end: 0 }.contains_range(AddressRange { start: 0, end: 5 })
287*bb4ee6a4SAndroid Build Coastguard Worker         );
288*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
289*bb4ee6a4SAndroid Build Coastguard Worker             !AddressRange { start: 5, end: 0 }.contains_range(AddressRange { start: 5, end: 0 })
290*bb4ee6a4SAndroid Build Coastguard Worker         );
291*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
292*bb4ee6a4SAndroid Build Coastguard Worker             !AddressRange { start: 5, end: 0 }.contains_range(AddressRange { start: 1, end: 3 })
293*bb4ee6a4SAndroid Build Coastguard Worker         );
294*bb4ee6a4SAndroid Build Coastguard Worker 
295*bb4ee6a4SAndroid Build Coastguard Worker         // An empty range is not contained by anything
296*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
297*bb4ee6a4SAndroid Build Coastguard Worker             !AddressRange { start: 0, end: 5 }.contains_range(AddressRange { start: 3, end: 1 })
298*bb4ee6a4SAndroid Build Coastguard Worker         );
299*bb4ee6a4SAndroid Build Coastguard Worker     }
300*bb4ee6a4SAndroid Build Coastguard Worker 
test_intersect(a: (u64, u64), b: (u64, u64), answer: (u64, u64))301*bb4ee6a4SAndroid Build Coastguard Worker     fn test_intersect(a: (u64, u64), b: (u64, u64), answer: (u64, u64)) {
302*bb4ee6a4SAndroid Build Coastguard Worker         let a = AddressRange {
303*bb4ee6a4SAndroid Build Coastguard Worker             start: a.0,
304*bb4ee6a4SAndroid Build Coastguard Worker             end: a.1,
305*bb4ee6a4SAndroid Build Coastguard Worker         };
306*bb4ee6a4SAndroid Build Coastguard Worker         let b = AddressRange {
307*bb4ee6a4SAndroid Build Coastguard Worker             start: b.0,
308*bb4ee6a4SAndroid Build Coastguard Worker             end: b.1,
309*bb4ee6a4SAndroid Build Coastguard Worker         };
310*bb4ee6a4SAndroid Build Coastguard Worker         let answer = AddressRange {
311*bb4ee6a4SAndroid Build Coastguard Worker             start: answer.0,
312*bb4ee6a4SAndroid Build Coastguard Worker             end: answer.1,
313*bb4ee6a4SAndroid Build Coastguard Worker         };
314*bb4ee6a4SAndroid Build Coastguard Worker 
315*bb4ee6a4SAndroid Build Coastguard Worker         // intersect() should be commutative, so try it both ways
316*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(a.intersect(b), answer);
317*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(b.intersect(a), answer);
318*bb4ee6a4SAndroid Build Coastguard Worker     }
319*bb4ee6a4SAndroid Build Coastguard Worker 
320*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
intersect()321*bb4ee6a4SAndroid Build Coastguard Worker     fn intersect() {
322*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect((0, 5), (0, 5), (0, 5));
323*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect((0, 5), (0, 3), (0, 3));
324*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect((0, 5), (3, 5), (3, 5));
325*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect((0, 5), (5, 5), (5, 5));
326*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect((0, 5), (4, 9), (4, 5));
327*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect((0, u64::MAX), (3, 5), (3, 5));
328*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect((10, 20), (5, 15), (10, 15));
329*bb4ee6a4SAndroid Build Coastguard Worker     }
330*bb4ee6a4SAndroid Build Coastguard Worker 
test_intersect_empty(a: (u64, u64), b: (u64, u64))331*bb4ee6a4SAndroid Build Coastguard Worker     fn test_intersect_empty(a: (u64, u64), b: (u64, u64)) {
332*bb4ee6a4SAndroid Build Coastguard Worker         let a = AddressRange {
333*bb4ee6a4SAndroid Build Coastguard Worker             start: a.0,
334*bb4ee6a4SAndroid Build Coastguard Worker             end: a.1,
335*bb4ee6a4SAndroid Build Coastguard Worker         };
336*bb4ee6a4SAndroid Build Coastguard Worker         let b = AddressRange {
337*bb4ee6a4SAndroid Build Coastguard Worker             start: b.0,
338*bb4ee6a4SAndroid Build Coastguard Worker             end: b.1,
339*bb4ee6a4SAndroid Build Coastguard Worker         };
340*bb4ee6a4SAndroid Build Coastguard Worker         assert!(a.intersect(b).is_empty());
341*bb4ee6a4SAndroid Build Coastguard Worker         assert!(b.intersect(a).is_empty());
342*bb4ee6a4SAndroid Build Coastguard Worker     }
343*bb4ee6a4SAndroid Build Coastguard Worker 
344*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
intersect_empty()345*bb4ee6a4SAndroid Build Coastguard Worker     fn intersect_empty() {
346*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect_empty((0, 5), (10, 20));
347*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect_empty((5, 0), (3, 4));
348*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect_empty((10, 20), (20, 10));
349*bb4ee6a4SAndroid Build Coastguard Worker         test_intersect_empty((10, 20), (30, 40));
350*bb4ee6a4SAndroid Build Coastguard Worker     }
351*bb4ee6a4SAndroid Build Coastguard Worker 
352*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
non_overlapping_ranges()353*bb4ee6a4SAndroid Build Coastguard Worker     fn non_overlapping_ranges() {
354*bb4ee6a4SAndroid Build Coastguard Worker         // Two identical ranges have no non-overlapping ranges.
355*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
356*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 0, end: 100 }
357*bb4ee6a4SAndroid Build Coastguard Worker                 .non_overlapping_ranges(AddressRange { start: 0, end: 100 }),
358*bb4ee6a4SAndroid Build Coastguard Worker             (AddressRange::empty(), AddressRange::empty())
359*bb4ee6a4SAndroid Build Coastguard Worker         );
360*bb4ee6a4SAndroid Build Coastguard Worker 
361*bb4ee6a4SAndroid Build Coastguard Worker         // Non-overlapping regions on both sides.
362*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
363*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 0, end: 100 }
364*bb4ee6a4SAndroid Build Coastguard Worker                 .non_overlapping_ranges(AddressRange { start: 10, end: 20 }),
365*bb4ee6a4SAndroid Build Coastguard Worker             (
366*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange { start: 0, end: 9 },
367*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange {
368*bb4ee6a4SAndroid Build Coastguard Worker                     start: 21,
369*bb4ee6a4SAndroid Build Coastguard Worker                     end: 100
370*bb4ee6a4SAndroid Build Coastguard Worker                 }
371*bb4ee6a4SAndroid Build Coastguard Worker             )
372*bb4ee6a4SAndroid Build Coastguard Worker         );
373*bb4ee6a4SAndroid Build Coastguard Worker 
374*bb4ee6a4SAndroid Build Coastguard Worker         // Non-overlapping region on the left but not on the right.
375*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
376*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 0, end: 100 }.non_overlapping_ranges(AddressRange {
377*bb4ee6a4SAndroid Build Coastguard Worker                 start: 10,
378*bb4ee6a4SAndroid Build Coastguard Worker                 end: 100
379*bb4ee6a4SAndroid Build Coastguard Worker             }),
380*bb4ee6a4SAndroid Build Coastguard Worker             (AddressRange { start: 0, end: 9 }, AddressRange::empty())
381*bb4ee6a4SAndroid Build Coastguard Worker         );
382*bb4ee6a4SAndroid Build Coastguard Worker 
383*bb4ee6a4SAndroid Build Coastguard Worker         // Non-overlapping region on the right but not on the left.
384*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
385*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 0, end: 100 }
386*bb4ee6a4SAndroid Build Coastguard Worker                 .non_overlapping_ranges(AddressRange { start: 0, end: 50 }),
387*bb4ee6a4SAndroid Build Coastguard Worker             (
388*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange::empty(),
389*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange {
390*bb4ee6a4SAndroid Build Coastguard Worker                     start: 51,
391*bb4ee6a4SAndroid Build Coastguard Worker                     end: 100
392*bb4ee6a4SAndroid Build Coastguard Worker                 }
393*bb4ee6a4SAndroid Build Coastguard Worker             )
394*bb4ee6a4SAndroid Build Coastguard Worker         );
395*bb4ee6a4SAndroid Build Coastguard Worker 
396*bb4ee6a4SAndroid Build Coastguard Worker         // Other range not contained within this range and greater than this range.
397*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
398*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 0, end: 100 }.non_overlapping_ranges(AddressRange {
399*bb4ee6a4SAndroid Build Coastguard Worker                 start: 200,
400*bb4ee6a4SAndroid Build Coastguard Worker                 end: 300
401*bb4ee6a4SAndroid Build Coastguard Worker             }),
402*bb4ee6a4SAndroid Build Coastguard Worker             (AddressRange { start: 0, end: 100 }, AddressRange::empty())
403*bb4ee6a4SAndroid Build Coastguard Worker         );
404*bb4ee6a4SAndroid Build Coastguard Worker 
405*bb4ee6a4SAndroid Build Coastguard Worker         // Other range not contained within this range and less than this range.
406*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
407*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange {
408*bb4ee6a4SAndroid Build Coastguard Worker                 start: 200,
409*bb4ee6a4SAndroid Build Coastguard Worker                 end: 300
410*bb4ee6a4SAndroid Build Coastguard Worker             }
411*bb4ee6a4SAndroid Build Coastguard Worker             .non_overlapping_ranges(AddressRange { start: 0, end: 100 }),
412*bb4ee6a4SAndroid Build Coastguard Worker             (
413*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange::empty(),
414*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange {
415*bb4ee6a4SAndroid Build Coastguard Worker                     start: 200,
416*bb4ee6a4SAndroid Build Coastguard Worker                     end: 300
417*bb4ee6a4SAndroid Build Coastguard Worker                 }
418*bb4ee6a4SAndroid Build Coastguard Worker             )
419*bb4ee6a4SAndroid Build Coastguard Worker         );
420*bb4ee6a4SAndroid Build Coastguard Worker 
421*bb4ee6a4SAndroid Build Coastguard Worker         // Partially overlapping region with non-overlapping region on the left.
422*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
423*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 10, end: 20 }
424*bb4ee6a4SAndroid Build Coastguard Worker                 .non_overlapping_ranges(AddressRange { start: 15, end: 35 }),
425*bb4ee6a4SAndroid Build Coastguard Worker             (AddressRange { start: 10, end: 14 }, AddressRange::empty())
426*bb4ee6a4SAndroid Build Coastguard Worker         );
427*bb4ee6a4SAndroid Build Coastguard Worker 
428*bb4ee6a4SAndroid Build Coastguard Worker         // Partially overlapping region with non-overlapping region on the right.
429*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
430*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 10, end: 20 }
431*bb4ee6a4SAndroid Build Coastguard Worker                 .non_overlapping_ranges(AddressRange { start: 5, end: 15 }),
432*bb4ee6a4SAndroid Build Coastguard Worker             (AddressRange::empty(), AddressRange { start: 16, end: 20 })
433*bb4ee6a4SAndroid Build Coastguard Worker         );
434*bb4ee6a4SAndroid Build Coastguard Worker     }
435*bb4ee6a4SAndroid Build Coastguard Worker 
436*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
split_at()437*bb4ee6a4SAndroid Build Coastguard Worker     fn split_at() {
438*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
439*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 10, end: 20 }.split_at(15),
440*bb4ee6a4SAndroid Build Coastguard Worker             (
441*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange { start: 10, end: 14 },
442*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange { start: 15, end: 20 }
443*bb4ee6a4SAndroid Build Coastguard Worker             )
444*bb4ee6a4SAndroid Build Coastguard Worker         );
445*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
446*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 10, end: 20 }.split_at(20),
447*bb4ee6a4SAndroid Build Coastguard Worker             (
448*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange { start: 10, end: 19 },
449*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange { start: 20, end: 20 }
450*bb4ee6a4SAndroid Build Coastguard Worker             )
451*bb4ee6a4SAndroid Build Coastguard Worker         );
452*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
453*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 10, end: 20 }.split_at(10),
454*bb4ee6a4SAndroid Build Coastguard Worker             (AddressRange { start: 10, end: 20 }, AddressRange::empty())
455*bb4ee6a4SAndroid Build Coastguard Worker         );
456*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
457*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 10, end: 20 }.split_at(21),
458*bb4ee6a4SAndroid Build Coastguard Worker             (AddressRange { start: 10, end: 20 }, AddressRange::empty())
459*bb4ee6a4SAndroid Build Coastguard Worker         );
460*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
461*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange { start: 10, end: 20 }.split_at(9),
462*bb4ee6a4SAndroid Build Coastguard Worker             (AddressRange { start: 10, end: 20 }, AddressRange::empty())
463*bb4ee6a4SAndroid Build Coastguard Worker         );
464*bb4ee6a4SAndroid Build Coastguard Worker     }
465*bb4ee6a4SAndroid Build Coastguard Worker 
466*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
from_start_and_size_valid()467*bb4ee6a4SAndroid Build Coastguard Worker     fn from_start_and_size_valid() {
468*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
469*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange::from_start_and_size(0x100, 0x20),
470*bb4ee6a4SAndroid Build Coastguard Worker             Some(AddressRange {
471*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x100,
472*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x11f
473*bb4ee6a4SAndroid Build Coastguard Worker             })
474*bb4ee6a4SAndroid Build Coastguard Worker         );
475*bb4ee6a4SAndroid Build Coastguard Worker 
476*bb4ee6a4SAndroid Build Coastguard Worker         // Max-sized range based at 0
477*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
478*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange::from_start_and_size(0, u64::MAX),
479*bb4ee6a4SAndroid Build Coastguard Worker             Some(AddressRange {
480*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0,
481*bb4ee6a4SAndroid Build Coastguard Worker                 end: u64::MAX - 1
482*bb4ee6a4SAndroid Build Coastguard Worker             })
483*bb4ee6a4SAndroid Build Coastguard Worker         );
484*bb4ee6a4SAndroid Build Coastguard Worker 
485*bb4ee6a4SAndroid Build Coastguard Worker         // Max-sized range based at 1
486*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
487*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange::from_start_and_size(1, u64::MAX),
488*bb4ee6a4SAndroid Build Coastguard Worker             Some(AddressRange {
489*bb4ee6a4SAndroid Build Coastguard Worker                 start: 1,
490*bb4ee6a4SAndroid Build Coastguard Worker                 end: u64::MAX
491*bb4ee6a4SAndroid Build Coastguard Worker             })
492*bb4ee6a4SAndroid Build Coastguard Worker         );
493*bb4ee6a4SAndroid Build Coastguard Worker 
494*bb4ee6a4SAndroid Build Coastguard Worker         // One-byte range based at u64::MAX
495*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
496*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange::from_start_and_size(u64::MAX, 1),
497*bb4ee6a4SAndroid Build Coastguard Worker             Some(AddressRange {
498*bb4ee6a4SAndroid Build Coastguard Worker                 start: u64::MAX,
499*bb4ee6a4SAndroid Build Coastguard Worker                 end: u64::MAX
500*bb4ee6a4SAndroid Build Coastguard Worker             })
501*bb4ee6a4SAndroid Build Coastguard Worker         );
502*bb4ee6a4SAndroid Build Coastguard Worker 
503*bb4ee6a4SAndroid Build Coastguard Worker         // Empty range (size = 0) with arbitrary start
504*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange::from_start_and_size(u64::MAX, 0)
505*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap()
506*bb4ee6a4SAndroid Build Coastguard Worker             .is_empty());
507*bb4ee6a4SAndroid Build Coastguard Worker     }
508*bb4ee6a4SAndroid Build Coastguard Worker 
509*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
from_start_and_size_invalid()510*bb4ee6a4SAndroid Build Coastguard Worker     fn from_start_and_size_invalid() {
511*bb4ee6a4SAndroid Build Coastguard Worker         // 2 + u64::MAX - 1 overflows
512*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(AddressRange::from_start_and_size(2, u64::MAX), None);
513*bb4ee6a4SAndroid Build Coastguard Worker 
514*bb4ee6a4SAndroid Build Coastguard Worker         // 0x100 + u64::MAX - 1 overflows
515*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(AddressRange::from_start_and_size(0x100, u64::MAX), None);
516*bb4ee6a4SAndroid Build Coastguard Worker 
517*bb4ee6a4SAndroid Build Coastguard Worker         // 0x100 + (u64::MAX - 0xfe) - 1 overflows
518*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
519*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange::from_start_and_size(0x100, u64::MAX - 0xfe),
520*bb4ee6a4SAndroid Build Coastguard Worker             None
521*bb4ee6a4SAndroid Build Coastguard Worker         );
522*bb4ee6a4SAndroid Build Coastguard Worker     }
523*bb4ee6a4SAndroid Build Coastguard Worker 
524*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
display()525*bb4ee6a4SAndroid Build Coastguard Worker     fn display() {
526*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
527*bb4ee6a4SAndroid Build Coastguard Worker             format!(
528*bb4ee6a4SAndroid Build Coastguard Worker                 "{}",
529*bb4ee6a4SAndroid Build Coastguard Worker                 AddressRange {
530*bb4ee6a4SAndroid Build Coastguard Worker                     start: 0x1234,
531*bb4ee6a4SAndroid Build Coastguard Worker                     end: 0x5678
532*bb4ee6a4SAndroid Build Coastguard Worker                 }
533*bb4ee6a4SAndroid Build Coastguard Worker             ),
534*bb4ee6a4SAndroid Build Coastguard Worker             "0x1234..=0x5678"
535*bb4ee6a4SAndroid Build Coastguard Worker         );
536*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(format!("{}", AddressRange::empty()), "empty");
537*bb4ee6a4SAndroid Build Coastguard Worker     }
538*bb4ee6a4SAndroid Build Coastguard Worker 
539*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
cmp()540*bb4ee6a4SAndroid Build Coastguard Worker     fn cmp() {
541*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
542*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange {
543*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x1000,
544*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x2000
545*bb4ee6a4SAndroid Build Coastguard Worker             } < AddressRange {
546*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x3000,
547*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x4000
548*bb4ee6a4SAndroid Build Coastguard Worker             }
549*bb4ee6a4SAndroid Build Coastguard Worker         );
550*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
551*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange {
552*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x1000,
553*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x2000
554*bb4ee6a4SAndroid Build Coastguard Worker             } == AddressRange {
555*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x1000,
556*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x2000
557*bb4ee6a4SAndroid Build Coastguard Worker             }
558*bb4ee6a4SAndroid Build Coastguard Worker         );
559*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
560*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange {
561*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x3000,
562*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x4000
563*bb4ee6a4SAndroid Build Coastguard Worker             } > AddressRange {
564*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x1000,
565*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x2000
566*bb4ee6a4SAndroid Build Coastguard Worker             }
567*bb4ee6a4SAndroid Build Coastguard Worker         );
568*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
569*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange {
570*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x1000,
571*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x2000
572*bb4ee6a4SAndroid Build Coastguard Worker             } < AddressRange {
573*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x1000,
574*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x3000
575*bb4ee6a4SAndroid Build Coastguard Worker             }
576*bb4ee6a4SAndroid Build Coastguard Worker         );
577*bb4ee6a4SAndroid Build Coastguard Worker     }
578*bb4ee6a4SAndroid Build Coastguard Worker 
579*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
cmp_empty()580*bb4ee6a4SAndroid Build Coastguard Worker     fn cmp_empty() {
581*bb4ee6a4SAndroid Build Coastguard Worker         // Empty ranges are less than any non-empty range and equal to any other empty range.
582*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
583*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange {
584*bb4ee6a4SAndroid Build Coastguard Worker                 start: 0x1000,
585*bb4ee6a4SAndroid Build Coastguard Worker                 end: 0x2000
586*bb4ee6a4SAndroid Build Coastguard Worker             } > AddressRange::empty()
587*bb4ee6a4SAndroid Build Coastguard Worker         );
588*bb4ee6a4SAndroid Build Coastguard Worker         assert!(
589*bb4ee6a4SAndroid Build Coastguard Worker             AddressRange::empty()
590*bb4ee6a4SAndroid Build Coastguard Worker                 < AddressRange {
591*bb4ee6a4SAndroid Build Coastguard Worker                     start: 0x1000,
592*bb4ee6a4SAndroid Build Coastguard Worker                     end: 0x2000
593*bb4ee6a4SAndroid Build Coastguard Worker                 }
594*bb4ee6a4SAndroid Build Coastguard Worker         );
595*bb4ee6a4SAndroid Build Coastguard Worker         assert!(AddressRange { start: 5, end: 3 } == AddressRange { start: 10, end: 1 });
596*bb4ee6a4SAndroid Build Coastguard Worker     }
597*bb4ee6a4SAndroid Build Coastguard Worker }
598