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