plate-tool/plate-tool-lib/src/csv/conversion.rs

91 lines
2.9 KiB
Rust

use crate::transfer::Transfer;
use crate::util::*;
use super::{alternative_formats::EchoClientTransferRecord, mangle_headers::mangle_headers, transfer_record::TransferRecordDeserializeIntermediate, TransferRecord};
use lazy_static::lazy_static;
use regex::Regex;
use std::error::Error;
pub fn transfer_to_records(
tr: &Transfer,
src_barcode: &str,
dest_barcode: &str,
) -> Vec<TransferRecord> {
let source_wells = tr.transfer_region.get_source_wells();
let map = tr.transfer_region.calculate_map();
let mut records: Vec<TransferRecord> = vec![];
for s_well in source_wells {
let dest_wells = map(s_well);
if let Some(dest_wells) = dest_wells {
for d_well in dest_wells {
records.push(TransferRecord {
source_plate: src_barcode.to_string(),
source_well: format!("{}{}", num_to_letters(s_well.0).unwrap(), s_well.1),
destination_plate: dest_barcode.to_string(),
destination_well: format!("{}{}", num_to_letters(d_well.0).unwrap(), d_well.1),
volume: tr.volume,
concentration: None,
})
}
}
}
records
}
pub fn records_to_csv(trs: Vec<TransferRecord>) -> Result<String, Box<dyn Error>> {
let mut wtr = csv::WriterBuilder::new().from_writer(vec![]);
for record in trs {
wtr.serialize(record)?
}
let data = String::from_utf8(wtr.into_inner()?)?;
Ok(data)
}
pub fn records_to_echo_client_csv(trs: Vec<TransferRecord>) -> Result<String, Box<dyn Error>> {
let mut wtr = csv::WriterBuilder::new().from_writer(vec![]);
for record in trs {
wtr.serialize(Into::<EchoClientTransferRecord>::into(record))?
}
let data = String::from_utf8(wtr.into_inner()?)?;
Ok(data)
}
/// Converts "spreadsheet format" well identification to coordinates
pub fn string_well_to_pt(input: &str) -> Option<(u8, u8)> {
lazy_static! {
static ref REGEX: Regex = Regex::new(r"([A-Z,a-z]+)(\d+)").unwrap();
// Can this be removed?
static ref REGEX_ALT: Regex = Regex::new(r"(\d+)").unwrap();
}
if let Some(c1) = REGEX.captures(input) {
if let (Some(row), Some(col)) = (letters_to_num(&c1[1]), c1[2].parse::<u8>().ok()) {
return Some((row, col))
} else {
return None
}
}
None
}
pub fn read_csv(data: &str) -> Vec<TransferRecord> {
let modified = mangle_headers(data);
let mut rdr = csv::Reader::from_reader(modified.as_bytes());
let mut records: Vec<TransferRecord> = Vec::new();
for record in rdr.deserialize::<TransferRecordDeserializeIntermediate>() {
match record {
Ok(r) => {
if !r.is_empty() {
records.push(r.into());
}
}
Err(e) => {
log::debug!("{:?}", e);
}
}
}
records
}