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
use core::panic::PanicInfo;
use std::{
    env,
    fs::File,
    io::{self, Write},
    path::{Path, PathBuf},
    process, writeln,
};

use indoc::indoc;
use preflight::{Avionics, Sensors};
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
use uuid::Uuid;

use crate::args::PanicHandleArguments;

pub fn panic_handle(
    panic_info: &PanicInfo,
    avionics: &dyn Avionics,
    sensors: &Sensors,
    args: &PanicHandleArguments,
) {
    let file_path = panic_file();

    {
        let mut file = File::create(&file_path).expect("Failed to create panic report file");

        write!(
            file,
            indoc! {"
                {:#?}
                
                //----INPUT----
                {:#?}
                
                //----CURRENT STATE----
                {:#?}
            "},
            panic_info, sensors, avionics
        )
        .expect("Failed to write to the panic report");
    }

    panic_alert(panic_info, &file_path).expect("Failed to warn the user of the panic");

    if args.open {
        open::that(file_path).expect("Failed to open the panic report");
    }

    process::exit(1);
}

pub fn panic_file() -> PathBuf {
    let uuid = Uuid::new_v4().to_hyphenated().to_string();
    let tmp_dir = env::temp_dir();
    let file_name = format!("{}.panic.rs", &uuid);
    Path::new(&tmp_dir).join(file_name)
}

pub fn panic_alert(panic_info: &PanicInfo, file: &Path) -> io::Result<()> {
    let mut stderr = StandardStream::stderr(ColorChoice::Auto);

    stderr.set_color(ColorSpec::new().set_fg(Some(Color::Red)).set_bold(true))?;
    writeln!(stderr, "\nGUIDANCE SYSTEM PANIC!")?;

    stderr.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
    writeln!(stderr, "{}", panic_info)?;

    stderr.set_color(ColorSpec::new().set_fg(Some(Color::Cyan)))?;
    write!(
        stderr,
        indoc! {"

            In flight this would trigger an auto abort, but should be avoided at all costs.
            Detailed information can be found at "
        }
    )?;

    stderr.set_color(
        ColorSpec::new()
            .set_intense(true)
            .set_fg(Some(Color::Magenta)),
    )?;
    writeln!(stderr, "{}", file.to_string_lossy())
}