1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum ErrorCode {
6 Parse,
8 Model,
10 Match,
12 Validation,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct FfiError {
19 pub code: ErrorCode,
21 pub message: String,
23}
24
25impl FfiError {
26 pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
28 FfiError {
29 code,
30 message: message.into(),
31 }
32 }
33}
34
35impl std::fmt::Display for FfiError {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 write!(f, "{:?}: {}", self.code, self.message)
38 }
39}
40
41impl std::error::Error for FfiError {}
42
43impl From<stix::pattern::ParseError> for FfiError {
44 fn from(e: stix::pattern::ParseError) -> Self {
45 FfiError::new(ErrorCode::Parse, e.to_string())
46 }
47}
48
49impl From<stix::model::ModelError> for FfiError {
50 fn from(e: stix::model::ModelError) -> Self {
51 FfiError::new(ErrorCode::Model, e.to_string())
52 }
53}
54
55impl From<stix::matcher::MatchError> for FfiError {
56 fn from(e: stix::matcher::MatchError) -> Self {
57 FfiError::new(ErrorCode::Match, e.to_string())
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn parse_error_maps_to_parse_code() {
67 let e = stix::parse("[bad").unwrap_err();
68 let f: FfiError = e.into();
69 assert_eq!(f.code, ErrorCode::Parse);
70 assert!(!f.message.is_empty());
71 }
72
73 #[test]
74 fn display_includes_code_and_message() {
75 let f = FfiError::new(ErrorCode::Validation, "missing field");
76 let s = format!("{f}");
77 assert!(s.contains("Validation"));
78 assert!(s.contains("missing field"));
79 }
80}