simctl/error.rs
1use std::process::{ExitStatus, Output};
2
3/// Error that is returned when the CLI does not successfully complete a
4/// request, or when the library encountered a problem while generating the
5/// request or while interpreting its response.
6#[derive(Debug)]
7pub enum Error {
8 /// This error is returned when the CLI exits with a non-zero exit code.
9 Output {
10 /// Contains the output written to stdout before the CLI exited with a
11 /// non-zero exit code.
12 stdout: String,
13
14 /// Contains the output written to stderr before the CLI exited with a
15 /// non-zero exit code.
16 stderr: String,
17
18 /// Contains the exit status.
19 status: ExitStatus,
20 },
21
22 /// This error is returned when the library failed spawning a new process
23 /// that runs the CLI. Most likely, this is caused by an incorrect Xcode
24 /// path. If the Xcode path was set automatically, Xcode is probably not
25 /// installed. If the Xcode path was set manually, it's probably incorrect.
26 /// Make sure that it ends with `Xcode(-*).app` (where * can be an optional
27 /// suffix to distinguish between stable and beta).
28 Io(std::io::Error),
29
30 /// This error is returned when the library failed to deserialize the
31 /// response of `simctl list -j` (in [`crate::list`]) or when it failed to
32 /// serialize a request for `simctl push` (in [`crate::push`]).
33 Json(serde_json::Error),
34
35 /// This error is returned when the library failed to interpret the CLI's
36 /// response as a UTF-8 encoded string.
37 Utf8(std::string::FromUtf8Error),
38}
39
40impl From<std::io::Error> for Error {
41 fn from(error: std::io::Error) -> Self {
42 Error::Io(error)
43 }
44}
45
46impl From<serde_json::Error> for Error {
47 fn from(error: serde_json::Error) -> Self {
48 Error::Json(error)
49 }
50}
51
52impl From<std::string::FromUtf8Error> for Error {
53 fn from(error: std::string::FromUtf8Error) -> Self {
54 Error::Utf8(error)
55 }
56}
57
58/// Partial application of the standard `Result` type, with the simctl [`Error`]
59/// pre-applied.
60pub type Result<T> = std::result::Result<T, Error>;
61
62pub trait Validate {
63 fn validate(self) -> Result<()>;
64 fn validate_with_output(self) -> Result<Output>;
65}
66
67impl Validate for Output {
68 fn validate(self) -> Result<()> {
69 let _ = self.validate_with_output()?;
70 Ok(())
71 }
72
73 fn validate_with_output(self) -> Result<Output> {
74 match self.status.success() {
75 true => Ok(self),
76 false => Err(Error::Output {
77 stdout: String::from_utf8(self.stdout).unwrap(),
78 stderr: String::from_utf8(self.stderr).unwrap(),
79 status: self.status,
80 }),
81 }
82 }
83}