1use std::cmp;
2use std::ops::Range;
3
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7pub type Position = u64;
8pub type Length = u64;
9
10pub trait AbstractInterval {
11 fn contig(&self) -> &str;
13 fn range(&self) -> Range<Position>;
15 fn contains<L>(&self, locus: L) -> bool
17 where
18 L: AbstractLocus,
19 {
20 self.contig() == locus.contig()
21 && locus.pos() >= self.range().start
22 && locus.pos() < self.range().end
23 }
24}
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26#[derive(new, Debug, PartialEq, Eq, Clone, Hash)]
27pub struct Interval {
28 contig: String,
29 range: Range<Position>,
30}
31
32impl PartialOrd for Interval {
33 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
34 Some(self.contig.cmp(&other.contig).then_with(|| {
35 self.range
36 .start
37 .cmp(&other.range.start)
38 .then_with(|| self.range.end.cmp(&other.range.end))
39 }))
40 }
41}
42
43impl Ord for Interval {
44 fn cmp(&self, other: &Self) -> cmp::Ordering {
45 self.partial_cmp(other).unwrap()
46 }
47}
48
49impl Interval {
50 pub fn range_mut(&mut self) -> &mut Range<Position> {
52 &mut self.range
53 }
54}
55
56impl AbstractInterval for Interval {
57 fn contig(&self) -> &str {
58 &self.contig
59 }
60
61 fn range(&self) -> Range<Position> {
62 self.range.clone()
63 }
64}
65
66pub trait AbstractLocus {
67 fn contig(&self) -> &str;
69 fn pos(&self) -> Position;
71}
72
73#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
74#[derive(new, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
75pub struct Locus {
76 contig: String,
77 pos: Position,
78}
79
80impl Locus {
81 pub fn pos_mut(&mut self) -> &mut Position {
83 &mut self.pos
84 }
85}
86
87impl AbstractLocus for Locus {
88 fn contig(&self) -> &str {
89 &self.contig
90 }
91
92 fn pos(&self) -> Position {
93 self.pos
94 }
95}