lldb/
error.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7use crate::{sys, ErrorType, SBStream};
8use std::fmt;
9use std::{error::Error, ffi::CStr};
10
11/// A container for holding any error code and an error message.
12///
13/// An `SBError` is used to indicate whether or not an operation
14/// has succeeded or failed, along with an indication of why it
15/// has failed.
16///
17/// To check if the operation has succeeded, use [`SBError::is_success()`].
18/// If it has failed, then [`SBError::is_failure()`] will return true,
19/// and more information about the error can be obtained from
20/// [`SBError::error()`], [`SBError::error_string()`], and
21/// [`SBError::error_type()`].
22pub struct SBError {
23    /// The underlying raw `SBErrorRef`.
24    pub raw: sys::SBErrorRef,
25}
26
27impl SBError {
28    /// Construct a new `SBError`.
29    pub(crate) fn wrap(raw: sys::SBErrorRef) -> SBError {
30        SBError { raw }
31    }
32
33    /// Construct a new `Some(SBError)` or `None`.
34    pub(crate) fn maybe_wrap(raw: sys::SBErrorRef) -> Option<SBError> {
35        if unsafe { sys::SBErrorIsValid(raw) } {
36            Some(SBError { raw })
37        } else {
38            None
39        }
40    }
41
42    /// Does this error represent a success?
43    ///
44    /// An error starts out in the success state by default:
45    ///
46    /// ```
47    /// # use lldb::SBError;
48    /// let e = SBError::default();
49    /// assert!(e.is_success());
50    /// ```
51    ///
52    /// See also:
53    ///
54    /// * [`SBError::into_result()`]
55    /// * [`SBError::is_failure()`]
56    pub fn is_success(&self) -> bool {
57        unsafe { sys::SBErrorSuccess(self.raw) }
58    }
59
60    /// Does this error represent a failure?
61    ///
62    /// See also:
63    ///
64    /// * [`SBError::error()`]
65    /// * [`SBError::error_string()`]
66    /// * [`SBError::error_type()`]
67    /// * [`SBError::into_result()`]
68    /// * [`SBError::is_success()`]
69    pub fn is_failure(&self) -> bool {
70        unsafe { sys::SBErrorFail(self.raw) }
71    }
72
73    /// Convert to a `Result<(), SBError>`.
74    ///
75    /// An `SBError` represents either a success or a failure. This method
76    /// converts the success variant to `Ok(())` and the error variant
77    /// to `Err(self)`.
78    ///
79    /// ```
80    /// # use lldb::SBError;
81    /// let e = SBError::default();
82    /// // Do something with `e`.
83    /// let r = e.into_result();
84    /// ```
85    ///
86    /// See also:
87    ///
88    /// * [`SBError::error()`]
89    /// * [`SBError::error_string()`]
90    /// * [`SBError::error_type()`]
91    pub fn into_result(self) -> Result<(), SBError> {
92        if self.is_success() {
93            Ok(())
94        } else {
95            Err(self)
96        }
97    }
98
99    /// The underlying error code. Must be interpreted in conjunction
100    /// with the error type.
101    ///
102    /// See also:
103    ///
104    /// * [`SBError::error_string()`]
105    /// * [`SBError::error_type()`]
106    pub fn error(&self) -> u32 {
107        unsafe { sys::SBErrorGetError(self.raw) }
108    }
109
110    /// Any textual error message associated with the error.
111    ///
112    /// See also:
113    ///
114    /// * [`SBError::error()`]
115    /// * [`SBError::error_type()`]
116    pub fn error_string(&self) -> &str {
117        unsafe {
118            match CStr::from_ptr(sys::SBErrorGetCString(self.raw)).to_str() {
119                Ok(s) => s,
120                _ => panic!("Invalid string?"),
121            }
122        }
123    }
124
125    /// What type of error is this?
126    ///
127    /// See also:
128    ///
129    /// * [`SBError::error()`]
130    /// * [`SBError::error_string()`]
131    pub fn error_type(&self) -> ErrorType {
132        unsafe { sys::SBErrorGetType(self.raw) }
133    }
134}
135
136impl Clone for SBError {
137    fn clone(&self) -> SBError {
138        SBError {
139            raw: unsafe { sys::CloneSBError(self.raw) },
140        }
141    }
142}
143
144impl Default for SBError {
145    fn default() -> SBError {
146        SBError::wrap(unsafe { sys::CreateSBError() })
147    }
148}
149
150impl fmt::Debug for SBError {
151    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
152        let stream = SBStream::new();
153        unsafe { sys::SBErrorGetDescription(self.raw, stream.raw) };
154        write!(fmt, "SBError {{ {} }}", stream.data())
155    }
156}
157
158impl fmt::Display for SBError {
159    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160        if self.is_success() {
161            write!(f, "SBError representing success")
162        } else {
163            write!(f, "SBError: {}", self.error_string())
164        }
165    }
166}
167
168impl Error for SBError {}
169
170impl Drop for SBError {
171    fn drop(&mut self) {
172        unsafe { sys::DisposeSBError(self.raw) };
173    }
174}
175
176unsafe impl Send for SBError {}
177unsafe impl Sync for SBError {}