use chrono::NaiveDate;
use crate::EDFSpecifications;
use crate::error::edf_error::EDFError;
use crate::utils::{deserialize_field, is_printable_ascii, serialize_field};
#[derive(Debug, Default, Clone, PartialEq)]
pub struct RecordingId {
pub startdate: Option<NaiveDate>,
pub admin_code: Option<String>, pub technician: Option<String>,
pub equipment: Option<String>,
pub additional: Vec<Option<String>>
}
impl RecordingId {
pub fn deserialize(value: String, spec: &EDFSpecifications) -> Result<Self, EDFError> {
let parts = value.split_ascii_whitespace().collect::<Vec<_>>();
if *spec == EDFSpecifications::EDFPlus && parts.len() >= 5 && parts[0] == "Startdate" {
return Ok(RecordingId {
startdate: deserialize_field(parts[1])
.map(|v| NaiveDate::parse_from_str(&v, "%d-%b-%Y"))
.transpose()
.map_err(|_| EDFError::InvalidRecordingIdDate)?,
admin_code: deserialize_field(parts[2]),
technician: deserialize_field(parts[3]),
equipment: deserialize_field(parts[4]),
additional: parts[5..].iter().cloned().map(deserialize_field).collect()
});
}
if *spec == EDFSpecifications::EDF {
let mut recording = RecordingId::default();
recording.admin_code = if value.is_empty() { None } else { Some(value) };
return Ok(recording);
}
Err(EDFError::InvalidRecordingIdSegmentCount)
}
pub fn serialize(&self, spec: &EDFSpecifications) -> Result<String, EDFError> {
let value = match spec {
EDFSpecifications::EDF => self.admin_code.clone().unwrap_or_default(),
EDFSpecifications::EDFPlus => {
let startdate = serialize_field(self.startdate.map(|d| d.format("%d-%b-%Y").to_string().to_uppercase()));
let admin_code = serialize_field(self.admin_code.clone());
let technician = serialize_field(self.technician.clone());
let equipment = serialize_field(self.equipment.clone());
let mut additional = self.additional.clone().into_iter().map(serialize_field).collect::<Vec<_>>().join(" ");
if !additional.is_empty() {
additional = format!(" {}", additional);
}
format!("Startdate {} {} {} {}{}", startdate, admin_code, technician, equipment, additional)
}
};
if value.len() > 80 {
return Err(EDFError::RecordingIdTooLong);
}
if !is_printable_ascii(&value) {
return Err(EDFError::InvalidASCII);
}
Ok(value)
}
}