use std::io;
use std::path::PathBuf;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum SelError {
#[error("invalid selector: {0}")]
InvalidSelector(String),
#[error("invalid regex: {0}")]
InvalidRegex(String),
#[error("positional selectors require a seekable file; stdin is line-only")]
PositionalWithStdin,
#[error("--invert-match requires --regex")]
InvertWithoutRegex,
#[error("--char-context requires --regex or a positional selector")]
CharContextWithoutTarget,
#[error("{path}: {source}")]
Io {
path: String,
#[source]
source: io::Error,
},
#[error("output file already exists: {} (use --force to overwrite)", .0.display())]
OutputExists(PathBuf),
}
pub type Result<T> = std::result::Result<T, SelError>;
#[cfg(test)]
mod tests {
use super::*;
use std::io;
use std::path::PathBuf;
#[test]
fn io_error_includes_path() {
let err = SelError::Io {
path: "nope.txt".into(),
source: io::Error::new(io::ErrorKind::NotFound, "no such"),
};
let msg = format!("{err}");
assert!(msg.contains("nope.txt"), "got: {msg}");
}
#[test]
fn positional_with_stdin_has_clear_message() {
let err = SelError::PositionalWithStdin;
let msg = format!("{err}");
assert!(msg.contains("stdin"));
}
#[test]
fn output_exists_names_path() {
let err = SelError::OutputExists(PathBuf::from("out.txt"));
let msg = format!("{err}");
assert!(msg.contains("out.txt"));
assert!(msg.contains("--force"));
}
}