use std::fmt::{Debug, Display};
use serde::{Deserialize, Serialize};
use crate::{
glycan::{GlycanPosition, MonoSaccharide},
sequence::{AminoAcid, Modification, SequencePosition},
};
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default, Debug, Serialize, Deserialize,
)]
#[non_exhaustive]
pub struct PeptidePosition {
pub sequence_index: SequencePosition,
pub series_number: usize,
pub sequence_length: usize,
}
impl PeptidePosition {
pub const fn n(sequence_index: SequencePosition, length: usize) -> Self {
Self {
sequence_index,
series_number: match sequence_index {
SequencePosition::NTerm => 0,
SequencePosition::Index(i) => i + 1,
SequencePosition::CTerm => length,
},
sequence_length: length,
}
}
pub const fn c(sequence_index: SequencePosition, length: usize) -> Self {
Self {
sequence_index,
series_number: match sequence_index {
SequencePosition::NTerm => length,
SequencePosition::Index(i) => length - i,
SequencePosition::CTerm => 0,
},
sequence_length: length,
}
}
pub fn is_n_terminal(&self) -> bool {
self.sequence_index == SequencePosition::NTerm
}
pub fn is_c_terminal(&self) -> bool {
self.sequence_index == SequencePosition::CTerm
}
#[must_use]
pub const fn flip_terminal(self) -> Self {
Self {
sequence_index: self.sequence_index,
series_number: self.sequence_length + 1 - self.series_number,
sequence_length: self.sequence_length,
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub enum DiagnosticPosition {
Glycan(GlycanPosition, MonoSaccharide),
GlycanCompositional(MonoSaccharide, Option<(AminoAcid, SequencePosition)>),
Peptide(PeptidePosition, AminoAcid),
Labile(Modification),
Reporter,
}
#[derive(
Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Serialize, Deserialize, Default,
)]
pub enum SatelliteLabel {
#[default]
None,
A,
B,
}
impl Display for SatelliteLabel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::None => "",
Self::A => "a",
Self::B => "b",
}
)
}
}
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub enum GlycanBreakPos {
End(GlycanPosition),
Y(GlycanPosition),
B(GlycanPosition),
}
impl GlycanBreakPos {
pub const fn position(&self) -> &GlycanPosition {
match self {
Self::B(p) | Self::End(p) | Self::Y(p) => p,
}
}
pub const fn label(&self) -> &str {
match self {
Self::End(_) => "End",
Self::Y(_) => "Y",
Self::B(_) => "B",
}
}
}
impl Display for GlycanBreakPos {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}{}", self.label(), self.position().label())
}
}