use std::error::Error;
use std::fmt;
#[derive(Debug)]
pub struct PipelineParseError {
pub file_path: String,
pub message: String,
}
impl fmt::Display for PipelineParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Failed to parse pipeline file '{}': {}\n\nSuggestion: Ensure the file exists and contains valid Azure DevOps YAML syntax.",
self.file_path, self.message
)
}
}
impl Error for PipelineParseError {}
#[derive(Debug)]
pub struct AzureCliError {
pub message: String,
}
impl fmt::Display for AzureCliError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Azure CLI error: {}\n\nSuggestion: Ensure Azure CLI is installed and you are logged in with 'az login'. \
Also verify the Azure DevOps extension is installed with 'az extension add --name azure-devops'.",
self.message
)
}
}
impl Error for AzureCliError {}
#[derive(Debug)]
pub struct VariableGroupNotFoundError {
pub group_name: String,
pub organization: String,
pub project: String,
}
impl fmt::Display for VariableGroupNotFoundError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Variable group '{}' not found in organization '{}', project '{}'.\n\n\
Suggestion: Verify the variable group name is correct and exists in Azure DevOps. \
You can create it at: https://dev.azure.com/{}/{}/_library?itemType=VariableGroups",
self.group_name, self.organization, self.project, self.organization, self.project
)
}
}
impl Error for VariableGroupNotFoundError {}
#[derive(Debug)]
pub struct VariableNotFoundError {
pub variable_name: String,
pub searched_groups: Vec<String>,
}
impl fmt::Display for VariableNotFoundError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.searched_groups.is_empty() {
write!(
f,
"Variable '{}' not found: No variable groups are referenced in the pipeline.\n\n\
Suggestion: Add a variable group reference to your pipeline YAML, or define the variable inline.",
self.variable_name
)
} else {
write!(
f,
"Variable '{}' not found in any of the referenced variable groups: {}.\n\n\
Suggestion: Add this variable to one of the referenced groups, or verify the variable name is spelled correctly.",
self.variable_name,
self.searched_groups.join(", ")
)
}
}
}
impl Error for VariableNotFoundError {}
#[derive(Debug)]
pub struct ValidationError {
pub context: String,
pub message: String,
}
impl fmt::Display for ValidationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Validation error while {}: {}\n\nSuggestion: Check your Azure DevOps connection and permissions.",
self.context, self.message
)
}
}
impl Error for ValidationError {}
pub struct OutputFormatter;
impl OutputFormatter {
pub fn success(message: &str) -> String {
format!(" [PASS] {message}")
}
pub fn failure(message: &str) -> String {
format!(" [FAIL] {message}")
}
pub fn info(message: &str) -> String {
format!(" [INFO] {message}")
}
pub fn warning(message: &str) -> String {
format!(" [WARN] {message}")
}
pub fn section(title: &str) -> String {
format!("\n{}\n{}", title, "-".repeat(title.len()))
}
pub fn summary(passed: usize, failed: usize) -> String {
let total = passed + failed;
if failed == 0 {
format!(
"\n================================\n\
RESULT: PASSED\n\
All {total} check(s) passed successfully.\n\
================================"
)
} else {
format!(
"\n================================\n\
RESULT: FAILED\n\
{failed} of {total} check(s) failed.\n\
================================"
)
}
}
}