#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct Location {
pub file_index: u16,
pub offset: u32,
pub len: u32,
}
impl Location {
pub fn new(file_index: u16, offset: usize, len: usize) -> Self {
Self {
file_index,
offset: u32::try_from(offset)
.expect("Location: offset exceeds u32::MAX (4GB file limit)"),
len: u32::try_from(len).expect("Location: len exceeds u32::MAX (4GB file limit)"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic(expected = "offset exceeds u32::MAX")]
fn new_panics_on_large_offset() {
Location::new(0, u32::MAX as usize + 1, 10);
}
#[test]
#[should_panic(expected = "len exceeds u32::MAX")]
fn new_panics_on_large_len() {
Location::new(0, 10, u32::MAX as usize + 1);
}
#[test]
fn test_location_eq() {
let loc1 = Location::new(0, 100, 50);
let loc2 = Location::new(0, 100, 50);
let loc3 = Location::new(1, 100, 50);
assert_eq!(loc1, loc2);
assert_ne!(loc1, loc3);
}
#[test]
fn test_location_hash() {
use std::collections::HashSet;
let loc1 = Location::new(0, 100, 50);
let loc2 = Location::new(0, 100, 50);
let loc3 = Location::new(1, 100, 50);
let mut set = HashSet::new();
set.insert(loc1);
assert!(set.contains(&loc2));
assert!(!set.contains(&loc3));
}
}