omics_coordinate/coordinate/
interbase.rs1use crate::Strand;
4use crate::contig;
5use crate::coordinate::Error;
6use crate::position;
7use crate::position::interbase::Position;
8use crate::strand;
9use crate::system::Base;
10use crate::system::Interbase;
11
12pub type Coordinate = crate::Coordinate<Interbase>;
14
15impl Coordinate {
16 pub fn nudge_forward(self) -> Option<crate::Coordinate<Base>> {
25 let (contig, strand, position) = self.into_parts();
26
27 let position = match strand {
28 Strand::Positive => position
29 .get()
30 .checked_add(1)
31 .and_then(|value| crate::Position::<Base>::try_new(value).ok()),
32 Strand::Negative => crate::Position::<Base>::try_new(position.get()).ok(),
33 }?;
34
35 Some(crate::Coordinate::new(contig, strand, position))
36 }
37
38 pub fn nudge_backward(self) -> Option<crate::Coordinate<Base>> {
47 let (contig, strand, position) = self.into_parts();
48
49 let position = match strand {
50 Strand::Positive => crate::Position::<Base>::try_new(position.get()).ok(),
51 Strand::Negative => position
52 .get()
53 .checked_add(1)
54 .and_then(|value| crate::Position::<Base>::try_new(value).ok()),
55 }?;
56
57 Some(crate::Coordinate::new(contig, strand, position))
58 }
59}
60
61impl crate::coordinate::r#trait::Coordinate<Interbase> for Coordinate {
62 fn try_new(
63 contig: impl TryInto<crate::Contig, Error = contig::Error>,
64 strand: impl TryInto<crate::Strand, Error = strand::Error>,
65 position: position::Number,
66 ) -> super::Result<Self> {
67 let contig = contig.try_into().map_err(Error::Contig)?;
68 let strand = strand.try_into().map_err(Error::Strand)?;
69 let position = Position::new(position);
70
71 Ok(Self {
72 system: Interbase,
73 contig,
74 strand,
75 position,
76 })
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use crate::base;
84 use crate::position::Number;
85
86 fn create_coordinate(contig: &str, strand: &str, position: Number) -> Coordinate {
87 Coordinate::try_new(contig, strand, position).unwrap()
88 }
89
90 fn create_base_coordinate(contig: &str, strand: &str, position: Number) -> base::Coordinate {
91 base::Coordinate::try_new(contig, strand, position).unwrap()
92 }
93
94 #[test]
95 fn nudge_forward() {
96 let coordinate = create_coordinate("seq0", "+", 0);
97 assert_eq!(
98 coordinate.nudge_forward().unwrap(),
99 create_base_coordinate("seq0", "+", 1)
100 );
101
102 let coordinate = create_coordinate("seq0", "+", 1);
103 assert_eq!(
104 coordinate.nudge_forward().unwrap(),
105 create_base_coordinate("seq0", "+", 2)
106 );
107
108 let coordinate = create_coordinate("seq0", "+", 10);
109 assert_eq!(
110 coordinate.nudge_forward().unwrap(),
111 create_base_coordinate("seq0", "+", 11)
112 );
113
114 let coordinate = create_coordinate("seq0", "+", Number::MAX);
115 assert!(coordinate.nudge_forward().is_none());
116
117 let coordinate = create_coordinate("seq0", "-", 0);
118 assert!(coordinate.nudge_forward().is_none());
119
120 let coordinate = create_coordinate("seq0", "-", 1);
121 assert_eq!(
122 coordinate.nudge_forward().unwrap(),
123 create_base_coordinate("seq0", "-", 1)
124 );
125
126 let coordinate = create_coordinate("seq0", "-", 10);
127 assert_eq!(
128 coordinate.nudge_forward().unwrap(),
129 create_base_coordinate("seq0", "-", 10)
130 );
131
132 let coordinate = create_coordinate("seq0", "-", Number::MAX);
133 assert_eq!(
134 coordinate.nudge_forward().unwrap(),
135 create_base_coordinate("seq0", "-", Number::MAX)
136 );
137 }
138
139 #[test]
140 fn nudge_backward() {
141 let coordinate = create_coordinate("seq0", "+", 0);
142 assert!(coordinate.nudge_backward().is_none());
143
144 let coordinate = create_coordinate("seq0", "+", 1);
145 assert_eq!(
146 coordinate.nudge_backward().unwrap(),
147 create_base_coordinate("seq0", "+", 1)
148 );
149
150 let coordinate = create_coordinate("seq0", "+", 10);
151 assert_eq!(
152 coordinate.nudge_backward().unwrap(),
153 create_base_coordinate("seq0", "+", 10)
154 );
155
156 let coordinate = create_coordinate("seq0", "+", Number::MAX);
157 assert_eq!(
158 coordinate.nudge_backward().unwrap(),
159 create_base_coordinate("seq0", "+", Number::MAX)
160 );
161
162 let coordinate = create_coordinate("seq0", "-", 0);
163 assert_eq!(
164 coordinate.nudge_backward().unwrap(),
165 create_base_coordinate("seq0", "-", 1)
166 );
167
168 let coordinate = create_coordinate("seq0", "-", 1);
169 assert_eq!(
170 coordinate.nudge_backward().unwrap(),
171 create_base_coordinate("seq0", "-", 2)
172 );
173
174 let coordinate = create_coordinate("seq0", "-", 10);
175 assert_eq!(
176 coordinate.nudge_backward().unwrap(),
177 create_base_coordinate("seq0", "-", 11)
178 );
179
180 let coordinate = create_coordinate("seq0", "-", Number::MAX);
181 assert!(coordinate.nudge_backward().is_none());
182 }
183}