use crate::Position;
use genomap::GenomeMapError;
use std::{
num::{ParseFloatError, ParseIntError},
string::FromUtf8Error,
};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum GRangesError {
#[error("File reading error: {0}. Please check if the file exists and you have permission to read it.")]
IOError(#[from] std::io::Error),
#[error("The specified file '{0}' is empty.")]
EmptyFile(String),
#[error("File parsing error: {0}")]
TsvParsingError(#[from] csv::Error),
#[error("Could not determine the file type based on its extension. Ensure the file has a standard genomic data extension (.bed, .gff, etc.).")]
CouldNotDetectRangesFiletype,
#[error("Error parsing an integer value: {0}. Check the file for non-integer entries where integers are expected.")]
ParseIntError(#[from] ParseIntError),
#[error("Error parsing a floating-point value: {0}. Check the file for non-numeric entries where floating-point numbers are expected.")]
ParseFloatError(#[from] ParseFloatError),
#[error(
"The provided BED file has fewer columns ({0}) than expected ({1}). Problematic line:\n{2}"
)]
BedTooFewColumns(usize, usize, String),
#[error("The provided BED3 file has fewer columns ({0}) than expected (3).\nAt least three columns are needed: sequence name, start, and end positions.\nProblematic line:\n{1}")]
Bed3TooFewColumns(usize, String),
#[error(
"Invalid column type: expected {expected_type} but got '{found_value}' in line: '{line}'."
)]
InvalidColumnType {
expected_type: String,
found_value: String,
line: String,
},
#[error("The input file had no rows.")]
NoRows,
#[error("The genome file is invalid: {0}. Please verify the file's format and contents.")]
InvalidGenomeFile(String),
#[error("Invalid BED format detected. Each entry must be '+', '-', or '.' to represent strand information.")]
InvalidString,
#[error("Attempted to unwrap genomic range data, but none was present. This operation requires data to be associated with each genomic range.")]
TryUnwrapDataError,
#[error("Attempted to unwrap genomic range data from a TSV with fewer than 4 columns. Ensure your TSV includes the necessary genomic range columns plus additional data.")]
TooFewColumns,
#[error("Invalid genomic range specified: start position ({0}) must be less than or equal to the end position ({1}).")]
InvalidGenomicRange(Position, Position),
#[error("The specified genomic range [{0}, {1}] is invalid for a sequence of length {2}. Adjust the range to fit within the sequence length.")]
InvalidGenomicRangeForSequence(Position, Position, Position),
#[error("The sequence name '{0}' is not found within the provided ranges container. Check the sequence names for typos or missing entries.")]
MissingSequence(String),
#[error("An error was encountered with the underlying genomap::GenomeMap: {0}")]
GenomeMapError(#[from] GenomeMapError),
#[error("The GRanges object is invalid because it lacks an associated data container. Ensure data is loaded or associated with the GRanges object before attempting operations that require data.")]
NoDataContainer,
#[error("The GRangesEmpty object cannot be united with this data because they are different lengths ({0} ≠ {1}")]
InvalidDataContainer(usize, usize),
#[error("The supplied GRanges object and data container cannot be united into a new GRanges since they have differing lengths.")]
IncompatableGRangesAndData,
#[error("The sequence name '{0}' was not found in the dataset. Verify the sequence names and try again.")]
MissingSequenceName(String),
#[error("An error occurred while converting bytes to a UTF-8 string. This often indicates invalid or corrupted data.")]
FromUtf8Error(#[from] FromUtf8Error),
#[error("The specified genomic range file format is unsupported. Check the documentation for a list of supported formats.")]
UnsupportedGenomicRangesFileFormat,
#[error("There was an error with the provided command line argument: {0}. Review the command line arguments for any mistakes.")]
ArgumentError(#[from] clap::error::Error),
#[error(
"The requested operation '{0}' does not exist. Check the list of supported operations."
)]
NoSuchOperation(String),
#[error("No operation was specified. See granges map --help.")]
NoOperationSpecified,
#[cfg(feature = "ndarray")]
#[error("Invalid shape encountered by ndarray: {0}")]
InvalidNdarrayShape(#[from] ndarray::ShapeError),
}