#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct SequencePosition {
pub start: isize,
pub start_insert: Option<String>,
pub end: isize,
pub end_insert: Option<String>,
}
impl SequencePosition {
#[must_use]
pub fn new(start: isize, start_insert: char, end: isize, end_insert: char) -> Self {
SequencePosition {
start,
start_insert: if start_insert == ' ' {
None
} else {
Some(String::from(start_insert))
},
end,
end_insert: if end_insert == ' ' {
None
} else {
Some(String::from(end_insert))
},
}
}
pub fn from_tuple((start, start_insert, end, end_insert): (isize, char, isize, char)) -> Self {
SequencePosition::new(start, start_insert, end, end_insert)
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct DatabaseReference {
pub database: Database,
pub pdb_position: SequencePosition,
pub database_position: SequencePosition,
pub differences: Vec<SequenceDifference>,
}
impl DatabaseReference {
#[must_use]
pub fn new(
database: impl Into<Database>,
pdb_position: SequencePosition,
database_position: SequencePosition,
) -> Self {
DatabaseReference {
database: database.into(),
pdb_position,
database_position,
differences: Vec::new(),
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct Database {
pub name: String,
pub acc: String,
pub id: String,
}
impl From<(String, String, String)> for Database {
fn from(database: (String, String, String)) -> Self {
Database {
name: database.0,
acc: database.1,
id: database.2,
}
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct SequenceDifference {
pub residue: (String, isize, Option<String>),
pub database_residue: Option<(String, isize)>,
pub comment: String,
}
impl SequenceDifference {
#[must_use]
pub const fn new(
residue: (String, isize, Option<String>),
database_residue: Option<(String, isize)>,
comment: String,
) -> Self {
SequenceDifference {
residue,
database_residue,
comment,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn check_database_reference() {
let pos_db = SequencePosition::new(10, ' ', 12, ' ');
let pos_seq = SequencePosition::new(10, ' ', 13, 'A');
let a = DatabaseReference::new(
("DB".to_string(), "ACC".to_string(), "ID".to_string()),
pos_seq.clone(),
pos_db.clone(),
);
let c = DatabaseReference::new(
("Z".to_string(), "ACC".to_string(), "ID".to_string()),
pos_seq.clone(),
pos_db.clone(),
);
assert_ne!(a, c);
assert_eq!(a.database_position, pos_db);
assert_eq!(a.pdb_position, pos_seq);
assert_eq!(a.differences, Vec::new());
format!("{a:?}");
assert!(a < c);
}
#[test]
fn check_sequence_position() {
let a = SequencePosition::new(10, ' ', 12, ' ');
let b = SequencePosition::from_tuple((10, ' ', 12, ' '));
let c = SequencePosition::from_tuple((11, ' ', 12, ' '));
assert_eq!(a, b);
assert_ne!(a, c);
assert_eq!(a.start, 10);
assert_eq!(a.start_insert, None);
assert_eq!(a.end, 12);
assert_eq!(a.end_insert, None);
format!("{a:?}");
assert!(a < c);
}
#[test]
fn check_sequence_difference() {
let a = SequenceDifference::new(
("ALA".to_string(), 10, None),
Some(("PHE".to_string(), 10)),
"Added phenyl group".to_string(),
);
let b = SequenceDifference::new(
("ALA".to_string(), 10, None),
Some(("PHE".to_string(), 13)),
"Added phenyl group".to_string(),
);
assert_ne!(a, b);
assert!(a < b);
format!("{a:?}");
}
}