1use num_traits::{CheckedAdd, Zero};
2use std::ops::Add;
3
4#[cfg(feature = "unwind")]
5pub fn resolve_filename(filename: &str, modulename: &str) -> Option<String> {
6 use std::path::Path;
8 let path = Path::new(filename);
9 if path.exists() {
10 return Some(filename.to_owned());
11 }
12
13 let module = Path::new(modulename);
15 if let Some(parent) = module.parent() {
16 if let Some(name) = path.file_name() {
17 let temp = parent.join(name);
18 if temp.exists() {
19 return Some(temp.to_string_lossy().to_string());
20 }
21 }
22 }
23
24 None
25}
26
27pub fn is_subrange<T: Eq + Ord + Add + CheckedAdd + Zero>(
28 start: T,
29 size: T,
30 sub_start: T,
31 sub_size: T,
32) -> bool {
33 !size.is_zero()
34 && !sub_size.is_zero()
35 && start.checked_add(&size).is_some()
36 && sub_start.checked_add(&sub_size).is_some()
37 && sub_start >= start
38 && sub_start + sub_size <= start + size
39}
40
41pub fn offset_of<T, M>(object: *const T, member: *const M) -> usize {
42 member as usize - object as usize
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn test_is_subrange() {
51 assert!(is_subrange(
52 0u64,
53 0xffff_ffff_ffff_ffff,
54 0,
55 0xffff_ffff_ffff_ffff
56 ));
57 assert!(is_subrange(0, 1, 0, 1));
58 assert!(is_subrange(0, 100, 0, 10));
59 assert!(is_subrange(0, 100, 90, 10));
60
61 assert!(!is_subrange(0, 0, 0, 0));
62 assert!(!is_subrange(1, 0, 0, 0));
63 assert!(!is_subrange(1, 0, 1, 0));
64 assert!(!is_subrange(0, 0, 0, 1));
65 assert!(!is_subrange(0, 0, 1, 0));
66 assert!(!is_subrange(
67 1u64,
68 0xffff_ffff_ffff_ffff,
69 0,
70 0xffff_ffff_ffff_ffff
71 ));
72 assert!(!is_subrange(
73 0u64,
74 0xffff_ffff_ffff_ffff,
75 1,
76 0xffff_ffff_ffff_ffff
77 ));
78 assert!(!is_subrange(0, 10, 0, 11));
79 assert!(!is_subrange(0, 10, 1, 10));
80 assert!(!is_subrange(0, 10, 9, 2));
81 }
82}