use thiserror::Error;
use crate::command::FliCommand;
#[derive(Debug, Error)]
pub enum FliError {
#[error("Command mismatch: expected '{expected}', got '{actual}'")]
CommandMismatch { expected: String, actual: String },
#[error("Unknown command: '{0}'. Run with --help to see available commands")]
UnknownCommand(String, Vec<String>),
#[error("Unknown option: '{0}'. Run with --help to see available options")]
UnknownOption(String),
#[error("Missing required value for option '{option}'")]
MissingValue { option: String },
#[error("Option '{option}' does not accept values, but '{value}' was provided")]
UnexpectedValue { option: String, value: String },
#[error("Option '{option}' expected {expected} value(s), got {actual}")]
ValueCountMismatch {
option: String,
expected: usize,
actual: usize,
},
#[error("Invalid value '{value}' for option '{option}': {reason}")]
InvalidValue {
option: String,
value: String,
reason: String,
},
#[error("Failed to parse '{value}' as {expected_type}: {reason}")]
ValueParseError {
value: String,
expected_type: String,
reason: String,
},
#[error("Invalid parse state transition from {from:?} to {to:?}")]
InvalidStateTransition { from: String, to: String },
#[error("Unexpected '{token}' at position {position}")]
UnexpectedToken { token: String, position: usize },
#[error("Invalid option configuration for '{option}': {reason}")]
InvalidOptionConfig { option: String, reason: String },
#[error("Invalid command configuration: {0}")]
InvalidCommandConfig(String),
#[error("Invalid flag format: '{flag}'. Flags must start with '-' or '--'")]
InvalidFlagFormat { flag: String },
#[error("Option '{0}' not found in parser")]
OptionNotFound(String),
#[error("Parser must be prepared before use. Call prepare() first")]
ParserNotPrepared,
#[error("Internal error: {0}")]
Internal(String),
#[error("Invalid usage: {0}. Run with --help to see correct usage")]
InvalidUsage(String),
}
impl FliError {
pub fn command_mismatch(expected: impl Into<String>, actual: impl Into<String>) -> Self {
Self::CommandMismatch {
expected: expected.into(),
actual: actual.into(),
}
}
pub fn missing_value(option: impl Into<String>) -> Self {
Self::MissingValue {
option: option.into(),
}
}
pub fn invalid_value(
option: impl Into<String>,
value: impl Into<String>,
reason: impl Into<String>,
) -> Self {
Self::InvalidValue {
option: option.into(),
value: value.into(),
reason: reason.into(),
}
}
pub fn value_count_mismatch(option: impl Into<String>, expected: usize, actual: usize) -> Self {
Self::ValueCountMismatch {
option: option.into(),
expected,
actual,
}
}
}
pub type Result<T> = std::result::Result<T, FliError>;