charon_error/submit/
simple_error_report.rs1use crate::{
2 ErrorFmt, ErrorFmtLoD, ErrorFmtSettings, ErrorReport, IndentationStyle, LinkDebugIde,
3 ResultExt, StringError, SubmitErrorReport,
4};
5use colored::Colorize;
6use std::sync::{OnceLock, RwLock, RwLockReadGuard};
7use url::Url;
8
9#[derive(Debug, Clone)]
29pub struct SimpleErrorReport<'a> {
30 pub error_report: &'a ErrorReport,
32}
33
34impl<'a> SubmitErrorReport<'a> for SimpleErrorReport<'a> {
35 fn new(error: &'a ErrorReport) -> Self {
36 SimpleErrorReport {
37 error_report: error,
38 }
39 }
40
41 fn get_error_report(&self) -> &ErrorReport {
42 self.error_report
43 }
44
45 fn get_title(&self) -> String {
46 self.error_report.get_last_error_title()
47 }
48
49 fn create_message(&self) -> Result<String, ErrorReport> {
50 self.create_bug_report()
51 }
52
53 fn create_bug_report(&self) -> Result<String, ErrorReport> {
54 let link_format = Self::get_global_config()
55 .map(|c| c.link_format)
56 .unwrap_or(LinkDebugIde::Vscode);
57
58 let last_error = self.get_title();
59
60 let mut report = String::new();
61
62 report.push_str(&format!("{}\n\n", "# Error Report".bright_cyan().bold()));
64
65 report.push_str(&format!("{}\n\n", "## Error".bright_cyan().bold()));
67 report.push_str(&format!("{}\n\n", last_error.bright_red().bold()));
68
69 let summary = self.error_report.stringify(ErrorFmtSettings {
71 level_of_detail: ErrorFmtLoD::SubmitReport,
72 frame_limit: None,
73 enable_color: true,
74 link_format,
75 indentation_style: IndentationStyle::TwoSpaces,
76 ..Default::default()
77 })?;
78 report.push_str(&format!("{}\n\n", "## Error report".bright_cyan().bold()));
79 report.push_str("```\n");
80 report.push_str(&summary);
81 report.push_str("\n```\n\n");
82
83 if let Some(last_frame) = self.error_report.frames.last() {
85 let backtrace_string = last_frame.create_backtrace_string();
86 if !backtrace_string.trim().is_empty() {
87 report.push_str(&format!("{}\n\n", "## Backtrace".bright_cyan().bold()));
88 report.push_str("```\n");
89 report.push_str(&backtrace_string);
90 report.push_str("```\n\n");
91 }
92 }
93
94 report.push_str(&format!("{}\n\n", "## System".bright_cyan().bold()));
96 report.push_str(&format!(
97 "* **OS:** {} {}\n",
98 std::env::consts::OS,
99 std::env::consts::ARCH
100 ));
101 report.push_str(&format!("* **Version:** {}\n", env!("CARGO_PKG_VERSION")));
102
103 Ok(report)
104 }
105
106 fn create_submit_url(&self) -> Result<Url, ErrorReport> {
107 Ok(Url::parse("data:text/plain,N/A")?)
108 }
109
110 fn create_submit_url_limited(&self, _max_length: usize) -> Result<Url, ErrorReport> {
111 Ok(Url::parse("data:text/plain,N/A")?)
112 }
113
114 fn check_existing_reports(&self) -> Result<Url, ErrorReport> {
115 Ok(Url::parse("data:text/plain,N/A")?)
116 }
117}
118
119impl<'a> SimpleErrorReport<'a> {
120 pub fn setup_global_config(config: SimpleERGlobalSettings) -> Result<(), ErrorReport> {
124 SIMPLE_REPORT_GLOBAL_CONFIG
125 .set(RwLock::new(config))
126 .map_err(|_| StringError::new("`SIMPLE_REPORT_GLOBAL_CONFIG` was already set"))
127 .change_context(SimpleGlobalSettingsError::AlreadySet)
128 }
129
130 pub fn get_global_config()
132 -> Result<RwLockReadGuard<'static, SimpleERGlobalSettings>, ErrorReport> {
133 let setting_reader = SIMPLE_REPORT_GLOBAL_CONFIG
134 .get()
135 .ok_or(SimpleGlobalSettingsError::SettingNotYetSet)?;
136 setting_reader
137 .read()
138 .map_err(StringError::from_error)
139 .change_context(SimpleGlobalSettingsError::AcquireReadLockFailed)
140 }
141}
142
143static SIMPLE_REPORT_GLOBAL_CONFIG: OnceLock<RwLock<SimpleERGlobalSettings>> = OnceLock::new();
144
145#[derive(Debug, Clone)]
150pub struct SimpleERGlobalSettings {
151 pub link_format: LinkDebugIde,
153}
154
155impl Default for SimpleERGlobalSettings {
156 fn default() -> Self {
157 Self {
158 link_format: LinkDebugIde::Vscode,
159 }
160 }
161}
162
163#[derive(thiserror::Error, Debug, Clone)]
164enum SimpleGlobalSettingsError {
165 #[error("Simple Global Settings where already set, this can only be set once.")]
166 AlreadySet,
167 #[error("Simple Global Settings where not set.")]
168 SettingNotYetSet,
169 #[error("Could not acquire read lock to read Simple Global Settings.")]
170 AcquireReadLockFailed,
171}