use thiserror::Error;
#[derive(Debug, Error, PartialEq, Eq)]
pub enum HostlistError {
#[error("empty bracket expression in '{expression}'")]
EmptyBracket { expression: String },
#[error("unclosed bracket in '{expression}'")]
UnclosedBracket { expression: String },
#[error("unmatched closing bracket in '{expression}'")]
UnmatchedBracket { expression: String },
#[error("invalid range syntax '{range}' in '{expression}': {reason}")]
InvalidRange {
expression: String,
range: String,
reason: String,
},
#[error("reversed range '{start}-{end}' in '{expression}' (start must be <= end)")]
ReversedRange {
expression: String,
start: i64,
end: i64,
},
#[error(
"range expansion would produce {count} hosts, exceeding limit of {limit} in '{expression}'"
)]
RangeTooLarge {
expression: String,
count: usize,
limit: usize,
},
#[error("invalid number '{value}' in range expression '{expression}'")]
InvalidNumber { expression: String, value: String },
#[error("hostfile not found: {path}")]
FileNotFound { path: String },
#[error("failed to read hostfile '{path}': {reason}")]
FileReadError { path: String, reason: String },
#[error("nested brackets are not supported in '{expression}'")]
NestedBrackets { expression: String },
#[error("cannot distinguish IPv6 literal from range expression in '{expression}'")]
Ipv6Ambiguity { expression: String },
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = HostlistError::EmptyBracket {
expression: "node[]".to_string(),
};
assert_eq!(err.to_string(), "empty bracket expression in 'node[]'");
let err = HostlistError::UnclosedBracket {
expression: "node[1-5".to_string(),
};
assert_eq!(err.to_string(), "unclosed bracket in 'node[1-5'");
let err = HostlistError::ReversedRange {
expression: "node[5-1]".to_string(),
start: 5,
end: 1,
};
assert_eq!(
err.to_string(),
"reversed range '5-1' in 'node[5-1]' (start must be <= end)"
);
}
}