use crate::{Message, Span};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum OrderField {
PatientId,
Accession,
ProcedureId,
StudyUid,
}
impl OrderField {
pub const ALL: [OrderField; 4] = [
OrderField::PatientId,
OrderField::Accession,
OrderField::ProcedureId,
OrderField::StudyUid,
];
pub fn path(self) -> &'static str {
match self {
OrderField::PatientId => "PID-3.1",
OrderField::Accession => "OBR-18",
OrderField::ProcedureId => "OBR-19",
OrderField::StudyUid => "ZDS-1.1",
}
}
pub fn label(self) -> &'static str {
match self {
OrderField::PatientId => "Patient ID",
OrderField::Accession => "Accession number",
OrderField::ProcedureId => "Requested procedure ID",
OrderField::StudyUid => "Study instance UID",
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Order {
pub patient_id: Option<String>,
pub accession: Option<String>,
pub procedure_id: Option<String>,
pub study_uid: Option<String>,
pub spans: Vec<(Span, OrderField)>,
}
impl Order {
pub fn extract(msg: &Message) -> Order {
let mut order = Order::default();
for field in OrderField::ALL {
let Some(span) = msg.get_span(field.path()) else {
continue;
};
let value = msg.decode(span.slice(msg.raw()));
let value = value.trim();
if value.is_empty() {
continue;
}
order.spans.push((span, field));
let slot = match field {
OrderField::PatientId => &mut order.patient_id,
OrderField::Accession => &mut order.accession,
OrderField::ProcedureId => &mut order.procedure_id,
OrderField::StudyUid => &mut order.study_uid,
};
*slot = Some(value.to_string());
}
order
}
pub fn get(&self, field: OrderField) -> Option<&str> {
match field {
OrderField::PatientId => self.patient_id.as_deref(),
OrderField::Accession => self.accession.as_deref(),
OrderField::ProcedureId => self.procedure_id.as_deref(),
OrderField::StudyUid => self.study_uid.as_deref(),
}
}
}