use std::{collections::HashMap, fmt::Display};
use crate::mzspeclib::{Attribute, Attributes};
#[derive(Clone, Debug)]
pub struct LibraryHeader {
pub format_version: String,
pub attributes: Attributes,
pub attribute_classes: HashMap<EntryType, Vec<AttributeSet>>,
}
impl Default for LibraryHeader {
fn default() -> Self {
Self {
format_version: "1.0".into(),
attributes: vec![Vec::new(); 1],
attribute_classes: HashMap::new(),
}
}
}
impl LibraryHeader {
pub const fn new(
format_version: String,
attributes: Attributes,
attribute_classes: HashMap<EntryType, Vec<AttributeSet>>,
) -> Self {
Self {
format_version,
attributes,
attribute_classes,
}
}
pub(crate) fn is_already_defined(
&self,
attribute: &Attribute,
entry: EntryType,
names: &[&str],
) -> bool {
self.attribute_classes
.get(&entry)
.iter()
.flat_map(|s| s.iter())
.filter(|s| names.contains(&s.id.as_str()))
.any(|s| {
s.attributes
.iter()
.flatten()
.any(|a| a.name == attribute.name && a.value.equivalent(&attribute.value))
})
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AttributeSet {
pub id: String,
pub namespace: EntryType,
pub attributes: Attributes,
}
impl PartialOrd for AttributeSet {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match self.id.partial_cmp(&other.id) {
Some(core::cmp::Ordering::Equal) => {}
ord => return ord,
}
match self.namespace.partial_cmp(&other.namespace) {
Some(core::cmp::Ordering::Equal) => {}
ord => return ord,
}
self.attributes.len().partial_cmp(&other.attributes.len())
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum EntryType {
Spectrum,
Analyte,
Interpretation,
Cluster,
}
impl Display for EntryType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Spectrum => "Spectrum",
Self::Analyte => "Analyte",
Self::Interpretation => "Interpretation",
Self::Cluster => "Cluster",
}
)
}
}