tesseract_swift_transport/
error.rs1use std::mem::ManuallyDrop;
2use thiserror;
3use tesseract_one::{Error as TError, ErrorKind};
4use tesseract_swift_utils::{error::{CError, CErrorCode, ErrorCode, SwiftError},
5 traits::TryAsRef, string::CString};
6
7#[repr(u32)]
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
10pub enum CTesseractErrorCode {
11 Logger = CErrorCode::Sentinel,
12 Cancelled,
13 Serialization,
14 Weird
15}
16
17impl ErrorCode for CTesseractErrorCode {
18 const FIRST: u32 = CTesseractErrorCode::Logger as u32;
19 #[allow(non_upper_case_globals)]
20 const Sentinel: u32 = CTesseractErrorCode::Weird as u32 + 1;
21}
22
23#[repr(C)]
24#[derive(Debug, thiserror::Error)]
25pub enum TesseractSwiftError {
26 #[error("TesseractSwiftError::Interop: {0}")]
27 Interop(CError),
28 #[error("TesseractSwiftError::Swift: {0}")]
29 Swift(SwiftError),
30 #[error("TesseractSwiftError::Logger: {0}")]
31 Logger(String),
32 #[error("TesseractSwiftError::Tesseract: {0}")]
33 Tesseract(TError),
34 #[error("TesseractSwiftError[{0}]: {1}")]
35 Custom(u32, String)
36}
37
38impl TesseractSwiftError {
39 pub fn is_cancelled(&self) -> bool {
40 match self {
41 Self::Tesseract(terror) => match terror.kind {
42 ErrorKind::Cancelled => true,
43 _ => false
44 },
45 _ => false
46 }
47 }
48}
49
50impl From<CError> for TesseractSwiftError {
51 fn from(value: CError) -> Self {
52 match CErrorCode::from_u32(value.code) {
53 Some(code) => match code {
54 CErrorCode::Swift => {
55 match SwiftError::try_from(&value) {
56 Err(err) => err.into(),
57 Ok(err) => Self::Swift(err)
58 }
59 },
60 _ => Self::Interop(value)
61 },
62 None => match CTesseractErrorCode::from_u32(value.code) {
63 Some(code) => match code {
64 CTesseractErrorCode::Logger => Self::Logger(value.reason.try_into().unwrap()),
65 CTesseractErrorCode::Cancelled =>
66 Self::Tesseract(TError::described(ErrorKind::Cancelled, value.reason.try_as_ref().unwrap())),
67 CTesseractErrorCode::Serialization =>
68 Self::Tesseract(TError::described(ErrorKind::Serialization, value.reason.try_as_ref().unwrap())),
69 CTesseractErrorCode::Weird =>
70 Self::Tesseract(TError::described(ErrorKind::Weird, value.reason.try_as_ref().unwrap())),
71 },
72 None => Self::Custom(value.code - CTesseractErrorCode::Sentinel, value.reason.try_into().unwrap())
73 }
74 }
75 }
76}
77
78impl From<TesseractSwiftError> for CError {
79 fn from(value: TesseractSwiftError) -> Self {
80 match value {
81 TesseractSwiftError::Interop(error) => error,
82 TesseractSwiftError::Swift(error) => match error.try_into() {
83 Err(err) => err,
84 Ok(err) => err
85 },
86 TesseractSwiftError::Logger(reason) =>
87 CError { code: CTesseractErrorCode::Logger as u32, reason: reason.into() },
88 TesseractSwiftError::Tesseract(error) => {
89 let reason = error.description.unwrap_or_default();
90 match error.kind {
91 ErrorKind::Cancelled =>
92 CError { code: CTesseractErrorCode::Cancelled as u32, reason: reason.into() },
93 ErrorKind::Serialization =>
94 CError { code: CTesseractErrorCode::Serialization as u32, reason: reason.into() },
95 ErrorKind::Weird =>
96 CError { code: CTesseractErrorCode::Weird as u32, reason: reason.into() }
97 }
98 },
99 TesseractSwiftError::Custom(code, reason) =>
100 CError { code: code + CTesseractErrorCode::Sentinel, reason: reason.into() }
101 }
102 }
103}
104
105impl From<TError> for TesseractSwiftError {
106 fn from(value: TError) -> Self {
107 match value.kind {
108 ErrorKind::Weird => {
109 let reason = value.description.unwrap_or_else(|| String::new());
110 let parts: Vec<&str> = reason.split(" :: ").collect();
111 if parts.len() != 2 {
112 return Self::Tesseract(TError::described(ErrorKind::Weird, &reason.clone()));
113 }
114 match parts[0].parse::<u32>() {
115 Err(_) => Self::Tesseract(TError::described(ErrorKind::Weird, &reason.clone())),
116 Ok(code) => CError::new(code, parts[1].to_owned()).into()
117 }
118 },
119 _ => Self::Tesseract(value)
120 }
121 }
122}
123
124impl From<TesseractSwiftError> for TError {
125 fn from(value: TesseractSwiftError) -> Self {
126 match value {
127 TesseractSwiftError::Tesseract(err) => err,
128 err => {
129 let cerr: CError = err.into();
130 TError::described(ErrorKind::Weird, &format!("{} :: {}", cerr.code, cerr.reason))
131 }
132 }
133 }
134}
135
136impl From<log::SetLoggerError> for TesseractSwiftError {
137 fn from(value: log::SetLoggerError) -> Self {
138 Self::Logger(value.to_string())
139 }
140}
141
142#[no_mangle]
143pub unsafe extern "C" fn tesseract_error_get_description(err: &CError) -> ManuallyDrop<CString> {
144 let tesseract: TesseractSwiftError = err.clone().into();
145 ManuallyDrop::new(tesseract.to_string().into())
146}