1use crate::ffi::{
2 c4error_getDescription, c4error_getMessage, C4Error, C4ErrorDomain, FLSliceResult,
3};
4use std::{fmt, os::raw::c_int};
5
6pub enum Error {
8 C4Error(C4Error),
10 InvalidUtf8,
12 LogicError(Box<str>),
14 SerdeFleece(serde_fleece::Error),
15 NulError(std::ffi::NulError),
17 InvalidQuery {
18 err: C4Error,
19 query_expr: Box<str>,
20 pos: c_int,
21 },
22}
23
24impl std::error::Error for Error {}
25
26pub(crate) type Result<T> = std::result::Result<T, Error>;
27
28impl fmt::Display for Error {
29 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
30 match self {
31 Error::C4Error(err) => {
32 let (msg, desc) = into_msg_desc(*err);
33 write!(
34 fmt,
35 "c4 error {}: {}",
36 desc.as_utf8_lossy(),
37 msg.as_utf8_lossy()
38 )
39 }
40 Error::InvalidUtf8 => fmt.write_str("Utf8 encoding error"),
41 Error::LogicError(msg) => write!(fmt, "logic error: {msg}"),
42 Error::SerdeFleece(err) => write!(fmt, "serde+flecce error: {err}"),
43 Error::NulError(err) => write!(fmt, "argument contains null character: {err}"),
44 Error::InvalidQuery {
45 pos,
46 query_expr,
47 err,
48 } => {
49 let (msg, desc) = into_msg_desc(*err);
50 write!(
51 fmt,
52 "Can not parse query {}, error at {}: {} {}",
53 query_expr,
54 pos,
55 desc.as_utf8_lossy(),
56 msg.as_utf8_lossy()
57 )
58 }
59 }
60 }
61}
62
63impl fmt::Debug for Error {
64 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
65 match self {
66 Error::C4Error(err) => {
67 let (msg, desc) = into_msg_desc(*err);
68 write!(
69 fmt,
70 "{:?} / {}: {}",
71 *err,
72 desc.as_utf8_lossy(),
73 msg.as_utf8_lossy()
74 )
75 }
76 Error::InvalidUtf8 => write!(fmt, "Invalid UTF-8 error"),
77 Error::LogicError(msg) => write!(fmt, "LogicError: {msg}"),
78 Error::SerdeFleece(err) => write!(fmt, "SerdeFleece error: {err}"),
79 Error::NulError(err) => write!(fmt, "NulError: {err:?}"),
80 Error::InvalidQuery {
81 pos,
82 query_expr,
83 err,
84 } => {
85 let (msg, desc) = into_msg_desc(*err);
86 write!(
87 fmt,
88 "InvalidQuery {{ query_expr {}, pos {}, err {:?} / {}: {} }}",
89 query_expr,
90 pos,
91 *err,
92 desc.as_utf8_lossy(),
93 msg.as_utf8_lossy()
94 )
95 }
96 }
97 }
98}
99
100impl From<C4Error> for Error {
101 fn from(err: C4Error) -> Self {
102 Error::C4Error(err)
103 }
104}
105
106impl From<serde_fleece::Error> for Error {
107 fn from(err: serde_fleece::Error) -> Self {
108 Error::SerdeFleece(err)
109 }
110}
111
112impl From<std::ffi::NulError> for Error {
113 fn from(err: std::ffi::NulError) -> Self {
114 Error::NulError(err)
115 }
116}
117
118pub(crate) fn c4error_init() -> C4Error {
119 C4Error {
120 domain: C4ErrorDomain::kC4MaxErrorDomainPlus1,
121 code: 0,
122 internal_info: 0,
123 }
124}
125
126fn into_msg_desc(err: C4Error) -> (FLSliceResult, FLSliceResult) {
127 let msg = unsafe { c4error_getMessage(err) };
128 let desc = unsafe { c4error_getDescription(err) };
129 (msg, desc)
130}