use std::error::Error as StdError;
use std::fmt;
use crossbeam_channel::SendError;
use thiserror::Error;
#[cfg(feature = "htslib")]
use crate::htslib::ParallelHtslibError;
#[cfg(feature = "htslib")]
use rust_htslib::errors::Error as HtslibError;
pub type Result<T> = std::result::Result<T, ProcessError>;
#[derive(Error, Debug)]
pub enum ProcessError {
#[error("Processing error: {0}")]
Process(Box<dyn StdError + Send + Sync>),
#[error("Invalid thread count specified")]
InvalidThreadCount,
#[error(
"Collection size mismatch, expected multiple of {} found {}",
arity,
found
)]
CollectionSizeMismatch { arity: usize, found: usize },
#[error("Incompatible readers specified, expected both readers to be the same input format")]
IncompatibleReaders,
#[error("Incompatible record set sizes: {0} != {1}")]
IncompatibleRecordSetSizes(usize, usize),
#[error("Incompatible interleaved set size - expected an even number: {0}")]
IncompatibleInterleavedSetSize(usize),
#[error("Record synchronization error between paired files. {0} has less records.")]
PairedRecordMismatch(RecordPair),
#[error(
"Record synchronization error between multiple files. (at least) File {0} has fewer records."
)]
MultiRecordMismatch(usize),
#[error("Record set length ({0}) must be divisible by {1}")]
MultiRecordSetSizeMismatch(usize, usize),
#[error("Channel error: {0}")]
SendError(#[from] SendError<Option<usize>>),
#[error("Thread join error.")]
JoinError,
#[error("I/O error: {0}")]
IoError(#[from] std::io::Error),
#[error("FASTX error: {0}")]
FastxError(#[from] crate::Error),
#[cfg(feature = "htslib")]
#[error("HTSlib error: {0}")]
HtslibError(#[from] HtslibError),
#[cfg(feature = "htslib")]
#[error("Parallel HTSlib error: {0}")]
ParallelHtslibError(#[from] ParallelHtslibError),
}
#[derive(Debug)]
pub enum RecordPair {
R1,
R2,
}
impl fmt::Display for RecordPair {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
RecordPair::R1 => write!(f, "R1"),
RecordPair::R2 => write!(f, "R2"),
}
}
}
pub trait IntoProcessError {
fn into_process_error(self) -> ProcessError;
}
impl<E> IntoProcessError for E
where
E: StdError + Send + Sync + 'static,
{
fn into_process_error(self) -> ProcessError {
ProcessError::Process(Box::new(self))
}
}
#[cfg(feature = "anyhow")]
impl From<anyhow::Error> for ProcessError {
fn from(err: anyhow::Error) -> Self {
ProcessError::Process(err.into())
}
}