use crate::target::{file_backer_upper, merge_rows, CompilationTarget, Csv, MergeResult};
use crate::{Result, Template};
impl CompilationTarget for Csv<'_> {
fn write_backup(&self) -> Result<()> {
file_backer_upper::backup_file(self.runtime, &self.path)?;
Ok(())
}
fn write(&self, template: &Template) -> Result<()> {
let existing_values = Self::read(&self.path, &self.runtime.output)?;
let new_values = template.spreadsheet.borrow();
let widest_row = new_values.widest_row();
let mut writer = csv::WriterBuilder::new()
.flexible(true)
.from_path(&self.path)
.map_err(|e| {
self.runtime
.output
.clone()
.into_error(format!("Unable to open output file for writing: {:?}", e))
})?;
for (index, row) in new_values.rows.iter().enumerate() {
let mut output_row: Vec<String> = merge_rows(
existing_values
.cells
.get(index)
.unwrap_or(&vec![].to_owned()),
&row.cells,
&self.runtime.options,
)
.iter()
.map(|cell| match cell {
MergeResult::New(v) => v.to_string(),
MergeResult::Existing(v) => v.to_string(),
MergeResult::Empty => "".to_owned(),
})
.collect();
output_row.resize(widest_row, "".to_string());
writer.write_record(output_row).map_err(|e| {
self.runtime
.output
.clone()
.into_error(format!("Unable to write row {index}: {e}"))
})?;
}
writer.flush().map_err(|e| {
self.runtime
.output
.clone()
.into_error(format!("Unable to finish writing to output: {e}"))
})?;
Ok(())
}
}
#[cfg(test)]
mod tests {
}