apple_clis/xcrun/simctl/boot/
output.rs1use crate::prelude::*;
2
3#[derive(Debug, Serialize)]
4#[non_exhaustive]
5#[must_use = include_doc!(must_use_cmd_output)]
6pub enum BootOutput {
7 AlreadyBooted,
9
10 #[doc = include_doc!(cmd_success)]
11 SuccessUnImplemented {
12 stdout: String,
13 },
14
15 #[doc = include_doc!(cmd_error)]
16 ErrorUnImplemented {
17 stderr: String,
18 },
19
20 ErrorLaunchDFailed {
31 stderr: String,
32 }
33}
34
35impl CommandNomParsable for BootOutput {
36 fn success_unimplemented(stdout: String) -> Self {
37 Self::SuccessUnImplemented { stdout }
38 }
39
40 fn error_unimplemented(stderr: String) -> Self {
41 Self::ErrorUnImplemented { stderr }
42 }
43
44 fn errored_nom_from_str(input: &str) -> IResult<&str, Self> {
45 alt((parse_already_booted, parse_launchd_failed))(input)
46 }
47}
48
49impl PublicCommandOutput for BootOutput {
50 type PrimarySuccess = ();
52
53 fn success(&self) -> Result<&Self::PrimarySuccess> {
54 match self {
55 BootOutput::SuccessUnImplemented { .. } | BootOutput::AlreadyBooted => Ok(&()),
56 BootOutput::ErrorLaunchDFailed { .. } => {
57 Err(Error::output_errored_with_hint(self, "Try running `sudo rm -rf ~/Library/Developer/CoreSimulator/Caches` to fix this issue."))
58 }
59 BootOutput::ErrorUnImplemented { .. } => Err(Error::output_errored(self)),
60 }
61 }
62}
63
64fn parse_already_booted(input: &str) -> IResult<&str, BootOutput> {
66 let (remaining, _preamble) = ws(tag("An error was encountered processing the command"))(input)?;
67 let (remaining, domain) =
68 delimited(tag("(domain="), take_till(|c| c == ','), tag(","))(remaining)?;
69 let (remaining, error_code) = delimited(ws(tag("code=")), digit1, ws(tag("):")))(remaining)?;
70 let (_, msg) =
71 all_consuming(ws(tag("Unable to boot device in current state: Booted")))(remaining)?;
72
73 warn!(?domain, ?error_code, ?msg, "Parsed xcrun simctl boot error");
74
75 Ok(("", BootOutput::AlreadyBooted))
76}
77
78fn parse_launchd_failed(input: &str) -> IResult<&str, BootOutput> {
83 let (remaining, _preamble) = ws(tag("An error was encountered processing the command"))(input)?;
84 let (remaining, domain) =
85 delimited(tag("(domain="), take_till(|c| c == ','), tag(","))(remaining)?;
86 let (remaining, error_code) = delimited(ws(tag("code=")), digit1, ws(tag("):")))(remaining)?;
87 let (underlying_error, msg) = ws(tag("launchd failed to respond."))(remaining)?;
88
89 warn!(?domain, ?error_code, ?msg, ?underlying_error, "Parsed xcrun simctl boot error");
90
91 Ok(("", BootOutput::ErrorLaunchDFailed { stderr: input.into() }))
92}