use crate::core::types::CellEdit;
use crate::model::Warning;
use crate::runtime::stateless::StatelessRuntime;
use anyhow::{Context, Result, bail};
use serde::Serialize;
use serde_json::Value;
use std::path::PathBuf;
#[derive(Debug, Serialize)]
struct CopyResponse {
source: String,
dest: String,
bytes_copied: u64,
}
#[derive(Debug, Serialize)]
struct EditResponse {
file: String,
sheet: String,
edits_applied: usize,
recalc_needed: bool,
warnings: Vec<Warning>,
}
pub async fn copy(source: PathBuf, dest: PathBuf) -> Result<Value> {
let runtime = StatelessRuntime;
let source = runtime.normalize_existing_file(&source)?;
let dest = runtime.normalize_destination_path(&dest)?;
let bytes_copied = runtime.copy_file(&source, &dest).with_context(|| {
format!(
"failed to copy workbook from '{}' to '{}'",
source.display(),
dest.display()
)
})?;
Ok(serde_json::to_value(CopyResponse {
source: source.display().to_string(),
dest: dest.display().to_string(),
bytes_copied,
})?)
}
pub async fn edit(file: PathBuf, sheet: String, edits: Vec<String>) -> Result<Value> {
if edits.is_empty() {
bail!("at least one edit must be provided");
}
let runtime = StatelessRuntime;
let file = runtime.normalize_existing_file(&file)?;
let mut normalized_edits = Vec::with_capacity(edits.len());
let mut warnings = Vec::new();
for (idx, entry) in edits.into_iter().enumerate() {
let (edit, entry_warnings) = crate::core::write::normalize_shorthand_edit(&entry)
.with_context(|| format!("invalid shorthand edit at index {}", idx))?;
normalized_edits.push(edit);
warnings.extend(entry_warnings.into_iter().map(|warning| Warning {
code: warning.code,
message: warning.message,
}));
}
runtime.apply_edits(&file, &sheet, &normalized_edits)?;
Ok(serde_json::to_value(EditResponse {
file: file.display().to_string(),
sheet,
edits_applied: normalized_edits.len(),
recalc_needed: true,
warnings,
})?)
}
pub fn parse_shorthand_for_tests(entries: Vec<String>) -> Result<(Vec<CellEdit>, Vec<Warning>)> {
let mut edits = Vec::with_capacity(entries.len());
let mut warnings = Vec::new();
for entry in entries {
let (edit, entry_warnings) = crate::core::write::normalize_shorthand_edit(&entry)?;
edits.push(edit);
warnings.extend(entry_warnings.into_iter().map(|warning| Warning {
code: warning.code,
message: warning.message,
}));
}
Ok((edits, warnings))
}