use std::collections::HashSet;
use std::fmt::{Debug, Display};
use std::hash::Hash;
use crate::annotations::disease::DiseaseIterator;
use crate::annotations::{AnnotationId, Disease};
use crate::term::HpoGroup;
use crate::HpoError;
use crate::HpoTermId;
pub type OrphaDiseases = HashSet<OrphaDiseaseId>;
#[derive(Clone, Copy, Default, Debug, Hash, PartialEq, PartialOrd, Eq, Ord)]
pub struct OrphaDiseaseId {
inner: u32,
}
impl AnnotationId for OrphaDiseaseId {
fn as_u32(&self) -> u32 {
self.inner
}
}
impl TryFrom<&str> for OrphaDiseaseId {
type Error = HpoError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
Ok(OrphaDiseaseId {
inner: value.parse::<u32>()?,
})
}
}
impl From<u32> for OrphaDiseaseId {
fn from(inner: u32) -> Self {
OrphaDiseaseId { inner }
}
}
impl Display for OrphaDiseaseId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ORPHA:{}", self.inner)
}
}
#[derive(Default, Debug, Clone)]
pub struct OrphaDisease {
id: OrphaDiseaseId,
name: String,
hpos: HpoGroup,
}
impl Disease for OrphaDisease {
type AnnoID = OrphaDiseaseId;
fn new(id: Self::AnnoID, name: &str) -> OrphaDisease {
Self {
name: name.to_string(),
id,
hpos: HpoGroup::default(),
}
}
fn id(&self) -> &Self::AnnoID {
&self.id
}
fn name(&self) -> &str {
&self.name
}
fn add_term<I: Into<HpoTermId>>(&mut self, term_id: I) -> bool {
self.hpos.insert(term_id)
}
fn hpo_terms(&self) -> &HpoGroup {
&self.hpos
}
}
impl PartialEq for OrphaDisease {
fn eq(&self, other: &OrphaDisease) -> bool {
self.id == other.id
}
}
impl Eq for OrphaDisease {}
impl TryFrom<&[u8]> for OrphaDisease {
type Error = HpoError;
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
Self::from_bytes(bytes)
}
}
impl Hash for OrphaDisease {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
pub type OrphaDiseaseIterator<'a> = DiseaseIterator<'a, OrphaDiseaseId>;
impl<'a> std::iter::Iterator for DiseaseIterator<'a, OrphaDiseaseId> {
type Item = &'a OrphaDisease;
fn next(&mut self) -> Option<Self::Item> {
self.diseases.next().map(|orpha_id| {
self.ontology
.orpha_disease(orpha_id)
.expect("disease must exist in Ontology")
})
}
}