ambassade_debug/
debug.rs

1use std::panic::Location;
2use std::marker::{Send, Sync};
3use std::fmt;
4
5/// The trait that needs to be implemented for using the `watch()` function.
6///
7/// # Example mockup
8/// ```
9/// pub struct MockType {}
10///
11/// impl SubmitMethod for MockType {
12///     fn submit(&self, info: &DebugInfo) -> bool {
13///         false
14///     }
15/// }
16/// ```
17
18pub trait SubmitMethod: Send + Sync {
19    /// The `submit()` function is used for submitting information about a crash of an exectuable
20    /// The return value of type 'bool' should indicate wether the
21    /// `DebugInfo` is submitted successfully.
22    fn submit(&self, info: &DebugInfo) -> bool;
23
24    /// This function will be called by `watch()` if the `submit()` function
25    /// returns 'true'.
26    /// # Default implementation
27    /// ```
28    /// fn submission_succeeded(&self, info: &DebugInfo) {
29    ///     println!("Thank you for your submission. We will investigate what happened A.S.A.P.");
30    /// }
31    /// ```
32    #[allow(unused_variables)]
33    fn submission_succeeded(&self, info: &DebugInfo) {
34        println!("Thank you for your submission. We will investigate what happened A.S.A.P.");
35    }
36
37    /// This function will be called by `watch()` if the `submit()` function
38    /// returns 'false'.
39    /// # Default implementation
40    /// ```
41    /// fn submission_failed(&self, info &DebugInfo) {
42    ///     println!("Something went wrong. Our apologies for the inconvenience. This information could not be sent:\n{}", info);
43    /// }
44    /// ```
45    fn submission_failed(&self, info: &DebugInfo) {
46        println!("Something went wrong. Our apologies for the inconvenience. This information could not be sent:\n{}", info);
47    }
48}
49
50/// A struct containing postmortem debug information that will be sent with
51/// something that implements the `SubmitMethod` trait, through `watch()`.
52pub struct DebugInfo<'a> {
53    sha: &'a str,
54    description: String,
55    info: &'a str,
56    location: Option<&'a Location<'a>>
57}
58
59impl<'a> DebugInfo<'a> {
60    pub fn new(sha: &'a str, desc: String, message: &'a str, panic_location: Option<&'a Location<'a>>) -> DebugInfo<'a> {
61        DebugInfo {
62            sha: sha,
63            description: desc,
64            info: message,
65            location: panic_location
66        }
67    }
68}
69
70impl<'a> fmt::Display for DebugInfo<'a> {
71    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72        let mut string = String::new();
73
74        string.push_str("tree: ");
75        string.push_str(self.sha);
76        string.push('\n');
77
78        string.push_str("at: ");
79
80        match self.location {
81            Some(location) => string.push_str(&location.to_string()),
82            None => string.push_str("<UNKOWN>")
83        }
84
85        string.push('\n');
86
87        string.push_str("Panic details: \n");
88        string.push_str(self.info);
89        string.push('\n');
90
91        string.push_str("Summary: \n");
92        string.push_str(&self.description);
93
94        try!(write!(f, "{}", string));
95        Ok(())
96    }
97}