feff10 0.2.2

Rust wrapper for FEFF10 X-ray absorption spectroscopy calculations
use std::fmt;
use std::io;

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    Parse(ParseError),
    Pipeline(PipelineError),
    Config(String),
}

#[derive(Debug)]
pub struct ParseError {
    pub line: usize,
    pub message: String,
}

#[derive(Debug)]
pub struct PipelineError {
    pub stage: String,
    pub exit_code: Option<i32>,
    pub stderr: String,
    pub feff_error: Option<String>,
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Error::Io(e) => write!(f, "I/O error: {e}"),
            Error::Parse(e) => write!(f, "Parse error at line {}: {}", e.line, e.message),
            Error::Pipeline(e) => {
                write!(f, "Pipeline error in stage '{}': {}", e.stage, e.stderr)?;
                if let Some(code) = e.exit_code {
                    write!(f, " (exit code: {code})")?;
                }
                if let Some(ref feff_err) = e.feff_error {
                    write!(f, "\n.feff.error: {feff_err}")?;
                }
                Ok(())
            }
            Error::Config(msg) => write!(f, "Config error: {msg}"),
        }
    }
}

impl std::error::Error for Error {}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self {
        Error::Io(e)
    }
}