grass_runtime/property/
region.rs

1use crate::ChrRef;
2
3pub trait RegionCore {
4    fn start(&self) -> u32;
5    fn end(&self) -> u32;
6    fn chrom(&self) -> ChrRef<'static>;
7
8    #[inline(always)]
9    fn empty(&self) -> bool {
10        self.end() <= self.start()
11    }
12
13    #[inline(always)]
14    fn length(&self) -> u32 {
15        self.end().max(self.start()) - self.start()
16    }
17}
18
19impl<'a> RegionCore for (ChrRef<'a>, u32, u32) {
20    fn start(&self) -> u32 {
21        self.1
22    }
23    fn end(&self) -> u32 {
24        self.2
25    }
26    fn chrom(&self) -> ChrRef<'static> {
27        self.0.to_static()
28    }
29}
30
31pub trait Region: RegionCore {
32    #[inline(always)]
33    fn overlaps(&self, b: &impl Region) -> bool {
34        let a = self;
35        if a.chrom() != b.chrom() {
36            return false;
37        }
38
39        !(a.end() <= b.start() || b.end() <= a.start())
40    }
41}
42
43impl<T: RegionCore> Region for T {}
44
45impl<T: Region> RegionCore for Option<T> {
46    #[inline(always)]
47    fn start(&self) -> u32 {
48        self.as_ref().map_or(0, |what| what.start())
49    }
50    #[inline(always)]
51    fn end(&self) -> u32 {
52        self.as_ref().map_or(0, |what| what.end())
53    }
54    #[inline(always)]
55    fn chrom(&self) -> ChrRef<'static> {
56        self.as_ref().map_or(ChrRef::Dummy, |what| what.chrom())
57    }
58}
59
60impl<'a, T: Region> RegionCore for &'a T {
61    #[inline(always)]
62    fn start(&self) -> u32 {
63        T::start(*self)
64    }
65    #[inline(always)]
66    fn end(&self) -> u32 {
67        T::end(*self)
68    }
69    #[inline(always)]
70    fn chrom(&self) -> ChrRef<'static> {
71        T::chrom(*self)
72    }
73}
74
75impl<A: Region, B: Region> RegionCore for (A, B) {
76    #[inline(always)]
77    fn start(&self) -> u32 {
78        if self.0.overlaps(&self.1) {
79            self.0.start().max(self.1.start())
80        } else {
81            0
82        }
83    }
84
85    #[inline(always)]
86    fn end(&self) -> u32 {
87        if self.0.overlaps(&self.1) {
88            self.0.end().min(self.1.end())
89        } else {
90            0
91        }
92    }
93
94    #[inline(always)]
95    fn chrom(&self) -> ChrRef<'static> {
96        self.0.chrom()
97    }
98}