use std::collections::BTreeMap;
use crate::release::{ANSWER_LINKS, ANSWER_LISTS, Release, ReleaseError, Table, csv_at, field};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Answer {
pub code: String,
pub display: String,
pub sequence: Option<u32>,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct AnswerList {
pub code: String,
pub name: String,
pub answers: Vec<Answer>,
pub terms: Vec<String>,
}
pub fn read(release: &Release) -> Result<BTreeMap<String, AnswerList>, ReleaseError> {
let mut lists: BTreeMap<String, AnswerList> = BTreeMap::new();
if let Some(path) = release.optional(ANSWER_LISTS) {
let mut table = Table::open(path)?;
let list_at = table.column("AnswerListId")?;
let name_at = table.column("AnswerListName")?;
let answer_at = table.column("AnswerStringId")?;
let display_at = table.column("DisplayText")?;
let sequence_at = table.column("SequenceNumber")?;
let path = table.path.clone();
for record in table.reader.records() {
let record = record.map_err(|e| csv_at(&path, e))?;
let code = field(&record, list_at).to_owned();
if code.is_empty() {
continue;
}
let list = lists.entry(code.clone()).or_insert_with(|| AnswerList {
code,
name: field(&record, name_at).to_owned(),
..AnswerList::default()
});
let answer = field(&record, answer_at);
if !answer.is_empty() {
list.answers.push(Answer {
code: answer.to_owned(),
display: field(&record, display_at).to_owned(),
sequence: field(&record, sequence_at).parse().ok(),
});
}
}
}
if let Some(path) = release.optional(ANSWER_LINKS) {
let mut table = Table::open(path)?;
let term_at = table.column("LoincNumber")?;
let list_at = table.column("AnswerListId")?;
let path = table.path.clone();
for record in table.reader.records() {
let record = record.map_err(|e| csv_at(&path, e))?;
let list = field(&record, list_at);
if let Some(entry) = lists.get_mut(list) {
entry.terms.push(field(&record, term_at).to_owned());
}
}
}
Ok(lists)
}