1use std::fmt;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum ExitCode {
5 Ok = 0,
6 Partial = 1,
7 SchemaError = 2,
8 StartupError = 3,
9 Timeout = 4,
10 ConfigError = 5,
11 IoError = 6,
12}
13
14impl From<ExitCode> for i32 {
15 fn from(code: ExitCode) -> Self {
16 code as i32
17 }
18}
19
20#[derive(Debug)]
21pub struct RokError {
22 pub code: ExitCode,
23 pub message: String,
24 pub context: Option<String>,
25}
26
27impl RokError {
28 pub fn new(code: ExitCode, message: impl Into<String>) -> Self {
29 Self {
30 code,
31 message: message.into(),
32 context: None,
33 }
34 }
35
36 pub fn with_context(mut self, context: impl Into<String>) -> Self {
37 self.context = Some(context.into());
38 self
39 }
40
41 pub fn schema(message: impl Into<String>) -> Self {
42 Self::new(ExitCode::SchemaError, message)
43 }
44
45 pub fn startup(message: impl Into<String>) -> Self {
46 Self::new(ExitCode::StartupError, message)
47 }
48
49 pub fn config(message: impl Into<String>) -> Self {
50 Self::new(ExitCode::ConfigError, message)
51 }
52
53 pub fn io(message: impl Into<String>) -> Self {
54 Self::new(ExitCode::IoError, message)
55 }
56
57 #[allow(dead_code)]
58 pub fn timeout(message: impl Into<String>) -> Self {
59 Self::new(ExitCode::Timeout, message)
60 }
61}
62
63impl fmt::Display for RokError {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 write!(f, "{}", self.message)?;
66 if let Some(ref ctx) = self.context {
67 write!(f, " (context: {})", ctx)?;
68 }
69 Ok(())
70 }
71}
72
73impl std::error::Error for RokError {}
74
75#[allow(dead_code)]
76#[derive(Debug)]
77pub struct StepError {
78 pub step_index: usize,
79 pub step_id: Option<String>,
80 pub message: String,
81}
82
83impl StepError {
84 #[allow(dead_code)]
85 pub fn new(step_index: usize, message: impl Into<String>) -> Self {
86 Self {
87 step_index,
88 step_id: None,
89 message: message.into(),
90 }
91 }
92
93 #[allow(dead_code)]
94 pub fn with_id(step_index: usize, step_id: String, message: impl Into<String>) -> Self {
95 Self {
96 step_index,
97 step_id: Some(step_id),
98 message: message.into(),
99 }
100 }
101}
102
103impl fmt::Display for StepError {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 if let Some(ref id) = self.step_id {
106 write!(
107 f,
108 "Step '{}' (index {}): {}",
109 id, self.step_index, self.message
110 )
111 } else {
112 write!(f, "Step {}: {}", self.step_index, self.message)
113 }
114 }
115}
116
117impl std::error::Error for StepError {}