use crate::models::Frame;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Exon {
start: u32,
end: u32,
cds_start: Option<u32>,
cds_end: Option<u32>,
frame_offset: Frame,
}
impl Exon {
pub fn new(
start: u32,
end: u32,
cds_start: Option<u32>,
cds_end: Option<u32>,
frame_offset: Frame,
) -> Exon {
Exon {
start,
end,
cds_start,
cds_end,
frame_offset,
}
}
pub fn start(&self) -> u32 {
self.start
}
pub fn start_mut(&mut self) -> &mut u32 {
&mut self.start
}
pub fn end(&self) -> u32 {
self.end
}
pub fn end_mut(&mut self) -> &mut u32 {
&mut self.end
}
pub fn cds_start(&self) -> &Option<u32> {
&self.cds_start
}
pub fn cds_start_mut(&mut self) -> &mut Option<u32> {
&mut self.cds_start
}
pub fn cds_end(&self) -> &Option<u32> {
&self.cds_end
}
pub fn cds_end_mut(&mut self) -> &mut Option<u32> {
&mut self.cds_end
}
pub fn frame_offset(&self) -> &Frame {
&self.frame_offset
}
pub fn frame_offset_mut(&mut self) -> &mut Frame {
&mut self.frame_offset
}
pub fn is_coding(&self) -> bool {
self.cds_start.is_some()
}
pub fn len(&self) -> u32 {
self.end - self.start + 1
}
pub fn is_empty(&self) -> bool {
false
}
pub fn coding_len(&self) -> u32 {
if !self.is_coding() {
return 0;
}
self.cds_end.unwrap() - self.cds_start.unwrap() + 1 }
pub fn downstream_frame(&self) -> Option<Frame> {
if !self.is_coding() {
return None;
}
let frame = (3 - (self.coding_len() % 3)) % 3;
match self.frame_offset + Frame::from_int(frame).unwrap() {
Ok(x) => Some(x),
Err(_) => None,
}
}
pub fn set_frame(&mut self, frame: Frame) {
self.frame_offset = frame;
}
}
impl fmt::Display for Exon {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"Exon ({}-{}) [{}-{}] ^{}^",
self.start,
self.end,
self.cds_start.unwrap_or(0),
self.cds_end.unwrap_or(0),
self.frame_offset
)
}
}