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