use crate::strings::alloc_c_string;
use kglite::api::KgErrorCode;
use std::ffi::c_char;
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KgliteStatusCode {
Ok = 0,
CypherSyntax = 1,
CypherTimeout = 2,
CypherExecution = 3,
CypherTypeMismatch = 4,
Schema = 5,
Validation = 6,
Expr = 7,
NodeNotFound = 8,
ConnectionNotFound = 9,
PropertyNotFound = 10,
FileNotFound = 11,
FileFormat = 12,
FileIo = 13,
InvalidArgument = 14,
MissingArgument = 15,
Internal = 16,
InvalidUtf8 = 100,
NullPointer = 101,
}
impl KgliteStatusCode {
pub(crate) fn from_kg_error_code(code: KgErrorCode) -> Self {
match code {
KgErrorCode::CypherSyntax => Self::CypherSyntax,
KgErrorCode::CypherTimeout => Self::CypherTimeout,
KgErrorCode::CypherExecution => Self::CypherExecution,
KgErrorCode::CypherTypeMismatch => Self::CypherTypeMismatch,
KgErrorCode::Schema => Self::Schema,
KgErrorCode::Validation => Self::Validation,
KgErrorCode::Expr => Self::Expr,
KgErrorCode::NodeNotFound => Self::NodeNotFound,
KgErrorCode::ConnectionNotFound => Self::ConnectionNotFound,
KgErrorCode::PropertyNotFound => Self::PropertyNotFound,
KgErrorCode::FileNotFound => Self::FileNotFound,
KgErrorCode::FileFormat => Self::FileFormat,
KgErrorCode::FileIo => Self::FileIo,
KgErrorCode::InvalidArgument => Self::InvalidArgument,
KgErrorCode::MissingArgument => Self::MissingArgument,
KgErrorCode::Internal => Self::Internal,
}
}
pub(crate) fn to_kg_error_code(self) -> Option<KgErrorCode> {
Some(match self {
Self::Ok | Self::InvalidUtf8 | Self::NullPointer => return None,
Self::CypherSyntax => KgErrorCode::CypherSyntax,
Self::CypherTimeout => KgErrorCode::CypherTimeout,
Self::CypherExecution => KgErrorCode::CypherExecution,
Self::CypherTypeMismatch => KgErrorCode::CypherTypeMismatch,
Self::Schema => KgErrorCode::Schema,
Self::Validation => KgErrorCode::Validation,
Self::Expr => KgErrorCode::Expr,
Self::NodeNotFound => KgErrorCode::NodeNotFound,
Self::ConnectionNotFound => KgErrorCode::ConnectionNotFound,
Self::PropertyNotFound => KgErrorCode::PropertyNotFound,
Self::FileNotFound => KgErrorCode::FileNotFound,
Self::FileFormat => KgErrorCode::FileFormat,
Self::FileIo => KgErrorCode::FileIo,
Self::InvalidArgument => KgErrorCode::InvalidArgument,
Self::MissingArgument => KgErrorCode::MissingArgument,
Self::Internal => KgErrorCode::Internal,
})
}
}
#[no_mangle]
pub extern "C" fn kglite_status_code_name(code: KgliteStatusCode) -> *const c_char {
let s = match code {
KgliteStatusCode::Ok => return std::ptr::null(),
KgliteStatusCode::InvalidUtf8 => "InvalidUtf8",
KgliteStatusCode::NullPointer => "NullPointer",
other => match other.to_kg_error_code() {
Some(kg) => kg.as_str(),
None => return std::ptr::null(),
},
};
alloc_c_string(s)
}
#[no_mangle]
pub extern "C" fn kglite_status_code_neo4j_status(code: KgliteStatusCode) -> *const c_char {
match code.to_kg_error_code() {
Some(kg) => alloc_c_string(kg.neo4j_status_code()),
None => std::ptr::null(),
}
}
#[no_mangle]
pub extern "C" fn kglite_status_code_http_status(code: KgliteStatusCode) -> u16 {
match code {
KgliteStatusCode::Ok => 0,
KgliteStatusCode::InvalidUtf8 | KgliteStatusCode::NullPointer => 400,
other => match other.to_kg_error_code() {
Some(kg) => kg.http_status_code(),
None => 500,
},
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_kg_error_code_round_trips() {
for code in [
KgErrorCode::CypherSyntax,
KgErrorCode::CypherTimeout,
KgErrorCode::CypherExecution,
KgErrorCode::CypherTypeMismatch,
KgErrorCode::Schema,
KgErrorCode::Validation,
KgErrorCode::Expr,
KgErrorCode::NodeNotFound,
KgErrorCode::ConnectionNotFound,
KgErrorCode::PropertyNotFound,
KgErrorCode::FileNotFound,
KgErrorCode::FileFormat,
KgErrorCode::FileIo,
KgErrorCode::InvalidArgument,
KgErrorCode::MissingArgument,
KgErrorCode::Internal,
] {
let c = KgliteStatusCode::from_kg_error_code(code);
let back = c.to_kg_error_code();
assert_eq!(back, Some(code), "round-trip failed for {code:?}");
}
}
#[test]
fn http_status_helpers_match_core() {
assert_eq!(
kglite_status_code_http_status(KgliteStatusCode::CypherSyntax),
400
);
assert_eq!(
kglite_status_code_http_status(KgliteStatusCode::NodeNotFound),
404
);
assert_eq!(
kglite_status_code_http_status(KgliteStatusCode::Internal),
500
);
assert_eq!(kglite_status_code_http_status(KgliteStatusCode::Ok), 0);
}
}