use xtalforge::core::Structure;
use xtalforge::io::write_structure;
use crate::Cli;
use crate::CliError;
use crate::format::StructureFormat;
pub(crate) fn resolve_format(
out: Option<&str>,
explicit: Option<StructureFormat>,
) -> StructureFormat {
explicit
.or_else(|| out.and_then(StructureFormat::from_path))
.unwrap_or(StructureFormat::Cif)
}
pub(crate) fn emit_structure(
cli: &Cli,
structure: &Structure,
out: Option<&str>,
explicit: Option<StructureFormat>,
) -> Result<(), CliError> {
let format = resolve_format(out, explicit);
let text = write_structure(structure, format.name()).map_err(CliError::core)?;
let destination = out.filter(|path| *path != "-");
if let Some(path) = destination {
write_destination(path, &text)?;
if cli.json {
let summary = structure.summary().map_err(CliError::core)?;
println!(
"{}",
serde_json::json!({
"format": format.name(),
"out": path,
"bytes": text.len(),
"summary": summary,
})
);
} else if !cli.quiet {
println!(
"wrote {} ({} sites, {} bytes) to {path}",
format.name(),
structure.sites().len(),
text.len()
);
}
return Ok(());
}
if cli.json {
let document = structure.to_document();
println!("{}", document.to_json().map_err(CliError::core)?);
} else {
print!("{text}");
}
Ok(())
}
pub(crate) fn write_destination(path: &str, text: &str) -> Result<(), CliError> {
xtalforge::io::atomic::write_text(std::path::Path::new(path), text).map_err(CliError::core)
}
pub(crate) fn write_bytes(path: &str, bytes: &[u8]) -> Result<(), CliError> {
if path == "-" {
use std::io::Write;
std::io::stdout().write_all(bytes).map_err(|error| {
CliError::new("io_error", format!("could not write stdout: {error}"))
})?;
return Ok(());
}
xtalforge::io::atomic::write_bytes(std::path::Path::new(path), bytes).map_err(CliError::core)
}