rust_diff_analyzer/
error.rs

1// SPDX-FileCopyrightText: 2025 RAprogramm <andrey.rozanov.vl@gmail.com>
2// SPDX-License-Identifier: MIT
3
4use std::path::PathBuf;
5
6use masterror::{AppCode, AppErrorKind, Error};
7
8/// Error for file read operations
9#[derive(Debug, Error)]
10#[error("failed to read file '{path}': {source}")]
11#[app_error(kind = AppErrorKind::Internal, code = AppCode::Internal, message)]
12pub struct FileReadError {
13    pub path: String,
14    pub source: std::io::Error,
15}
16
17impl FileReadError {
18    /// Creates a new FileReadError from a path and source error
19    pub fn new(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
20        Self {
21            path: path.into().display().to_string(),
22            source,
23        }
24    }
25}
26
27/// Error for Rust source code parsing
28#[derive(Debug, Error)]
29#[error("failed to parse '{path}': {message}")]
30#[app_error(kind = AppErrorKind::BadRequest, code = AppCode::BadRequest, message)]
31pub struct ParseError {
32    pub path: String,
33    pub message: String,
34}
35
36impl ParseError {
37    /// Creates a new ParseError from a path and message
38    pub fn new(path: impl Into<PathBuf>, message: impl Into<String>) -> Self {
39        Self {
40            path: path.into().display().to_string(),
41            message: message.into(),
42        }
43    }
44}
45
46/// Error for unified diff parsing
47#[derive(Debug, Error)]
48#[error("failed to parse diff: {message}")]
49#[app_error(kind = AppErrorKind::BadRequest, code = AppCode::BadRequest, message)]
50pub struct DiffParseError {
51    pub message: String,
52}
53
54/// Error for configuration file parsing
55#[derive(Debug, Error)]
56#[error("failed to parse config '{path}': {message}")]
57#[app_error(kind = AppErrorKind::BadRequest, code = AppCode::BadRequest, message)]
58pub struct ConfigError {
59    pub path: String,
60    pub message: String,
61}
62
63impl ConfigError {
64    /// Creates a new ConfigError from a path and message
65    pub fn new(path: impl Into<PathBuf>, message: impl Into<String>) -> Self {
66        Self {
67            path: path.into().display().to_string(),
68            message: message.into(),
69        }
70    }
71}
72
73/// Error for invalid configuration values
74#[derive(Debug, Error)]
75#[error("invalid config field '{field}': {message}")]
76#[app_error(kind = AppErrorKind::BadRequest, code = AppCode::BadRequest, message)]
77pub struct ConfigValidationError {
78    pub field: String,
79    pub message: String,
80}
81
82/// Error for output formatting
83#[derive(Debug, Error)]
84#[error("output error for format '{format}': {message}")]
85#[app_error(kind = AppErrorKind::Internal, code = AppCode::Internal, message)]
86pub struct OutputError {
87    pub format: String,
88    pub message: String,
89}
90
91/// Error for analysis limit exceeded
92#[derive(Debug, Error)]
93#[error("limit exceeded for '{limit_type}': {actual} > {maximum}")]
94#[app_error(kind = AppErrorKind::BadRequest, code = AppCode::BadRequest, message)]
95pub struct LimitExceededError {
96    pub limit_type: String,
97    pub actual: usize,
98    pub maximum: usize,
99}
100
101/// Error for IO operations
102#[derive(Debug, Error)]
103#[error("io error: {0}")]
104#[app_error(kind = AppErrorKind::Internal, code = AppCode::Internal, message)]
105pub struct IoError(pub std::io::Error);