1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
//! The way in which a command ends the process
//!
//! A command that returns `()` ends the process with the exit code 0, and a command that returns
//! an error ends it with the exit code 1. A command that needs a different ending returns an
//! [`Exit`], which carries the exit code and an optional text that the command rendered itself.
//!
//! An [`Exit`] is a plain value. The runner of an application returns it, and the `main`
//! function of the application ends the process with it.
use Debug;
use ExitCode;
use Builder;
use CopyGetters;
/// The exit code and the text with which a command ends the process
///
/// A wrapper, such as a script or a CI job, reads the exit code of a program to decide what to do
/// next. A command therefore needs to choose the code. The chosen code is not always a failure: a
/// check that finds a problem ends as planned, and it can still exit with a code other than 0 to
/// tell the wrapper what it found.
///
/// The text is what the command wants the user to read last, such as a diagnostic that the
/// application rendered itself. Clawless does not render the text. It writes the text to the
/// standard error once, exactly as it is, and adds no prefix and no line break. End the text with
/// a line break unless the text must not have one.
///
/// Clawless writes the text after it has rendered all the output that the command sent, and the
/// process exits after the text. The text therefore appears last on the standard error. The
/// standard output carries only the result of the command, so JSON output stays valid. The
/// verbosity does not apply to the text, so `--quiet` does not hide it.
///
/// An error that a command returns always ends the process with the exit code 1. A command that
/// needs another code for a failure turns the error into an `Exit` itself, and returns the `Exit`
/// in `Ok`.
///
/// Clawless itself uses these exit codes. A command can still use them, because Clawless reserves
/// none of them.
///
/// | Code | Meaning |
/// | ---- | -------------------------------------------------------------------------- |
/// | 0 | The command returned `()` |
/// | 1 | The command returned an error |
/// | 2 | The command line has an error, which the argument parser reports |
/// | 101 | The command or Clawless panicked, for example on a closed standard output |
/// | 130 | The user pressed Ctrl+C for the second time |
///
/// # Examples
///
/// ```
/// use std::process::ExitCode;
///
/// use clawless_core::exit::Exit;
///
/// let exit = Exit::builder()
/// .code(ExitCode::from(3))
/// .text("error: 0.7.0 is not a stable release\n")
/// .build();
///
/// assert_eq!(exit.code(), ExitCode::from(3));
/// assert_eq!(exit.text(), Some("error: 0.7.0 is not a stable release\n"));
/// ```
///
/// A command that only chooses the code converts an [`ExitCode`] into an `Exit` without text:
///
/// ```
/// use std::process::ExitCode;
///
/// use clawless_core::exit::Exit;
///
/// let exit = Exit::from(ExitCode::from(3));
///
/// assert_eq!(exit.text(), None);
/// ```
///
/// [`ExitCode`]: std::process::ExitCode
/// Returns the exit of a command that ended without a choice of its own
///
/// The exit code is 0, and the process writes no text.
/// Returns the exit with the given code and without text