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