#![allow(missing_docs)]
use noosphere_core::error::NoosphereError;
use safer_ffi::prelude::*;
impl From<NoosphereError> for NsError {
fn from(value: NoosphereError) -> Self {
NsError { inner: value }
}
}
impl From<NsError> for repr_c::Box<NsError> {
fn from(error: NsError) -> Self {
Box::new(error).into()
}
}
impl From<anyhow::Error> for NsError {
fn from(value: anyhow::Error) -> Self {
NsError::from(NoosphereError::from(value))
}
}
const NOOSPHERE_ERROR_OTHER: u32 = 1;
const NOOSPHERE_ERROR_NETWORK_OFFLINE: u32 = 2;
const NOOSPHERE_ERROR_NO_CREDENTIALS: u32 = 3;
const NOOSPHERE_ERROR_MISSING_CONFIGURATION: u32 = 4;
const NOOSPHERE_ERROR_INVALID_AUTHORIZATION: u32 = 5;
const NOOSPHERE_ERROR_UNEXPECTED_GATEWAY_RESPONSE: u32 = 6;
#[ffi_export]
#[derive_ReprC(rename = "ns_error_code")]
#[repr(u32)]
pub enum NsErrorCode {
Other = NOOSPHERE_ERROR_OTHER,
NetworkOffline = NOOSPHERE_ERROR_NETWORK_OFFLINE,
NoCredentials = NOOSPHERE_ERROR_NO_CREDENTIALS,
MissingConfiguration = NOOSPHERE_ERROR_MISSING_CONFIGURATION,
InvalidAuthorization = NOOSPHERE_ERROR_INVALID_AUTHORIZATION,
UnexpectedGatewayResponse = NOOSPHERE_ERROR_UNEXPECTED_GATEWAY_RESPONSE,
}
impl From<u32> for NsErrorCode {
fn from(code: u32) -> Self {
match code {
NOOSPHERE_ERROR_OTHER => NsErrorCode::Other,
NOOSPHERE_ERROR_NETWORK_OFFLINE => NsErrorCode::NetworkOffline,
NOOSPHERE_ERROR_NO_CREDENTIALS => NsErrorCode::NoCredentials,
NOOSPHERE_ERROR_MISSING_CONFIGURATION => NsErrorCode::MissingConfiguration,
NOOSPHERE_ERROR_INVALID_AUTHORIZATION => NsErrorCode::InvalidAuthorization,
_ => NsErrorCode::Other,
}
}
}
impl From<&NoosphereError> for NsErrorCode {
fn from(error: &NoosphereError) -> Self {
match error {
NoosphereError::Other(_) => NsErrorCode::Other,
NoosphereError::NetworkOffline => NsErrorCode::NetworkOffline,
NoosphereError::NoCredentials => NsErrorCode::NoCredentials,
NoosphereError::MissingConfiguration(_) => NsErrorCode::MissingConfiguration,
NoosphereError::InvalidAuthorization(_, _) => NsErrorCode::InvalidAuthorization,
NoosphereError::UnexpectedGatewayResponse(_) => NsErrorCode::UnexpectedGatewayResponse,
}
}
}
#[derive_ReprC(rename = "ns_error")]
#[repr(opaque)]
pub struct NsError {
inner: NoosphereError,
}
#[ffi_export]
pub fn ns_error_free(error: repr_c::Box<NsError>) {
drop(error)
}
#[ffi_export]
pub fn ns_error_message_get(error: &NsError) -> char_p::Box {
error
.inner
.to_string()
.try_into()
.unwrap_or_else(|_| char_p::new("Unknown"))
}
#[ffi_export]
pub fn ns_error_code_get(error: &NsError) -> u32 {
NsErrorCode::from(&error.inner) as u32
}
pub trait TryOrInitialize<E>: Sized
where
E: From<Self::InnerError>,
{
type InnerError;
fn try_or_initialize<T>(
self,
closure: impl FnOnce() -> Result<T, Self::InnerError>,
) -> Option<T> {
match closure() {
Ok(value) => Some(value),
Err(error) => {
self.late_initialize(E::from(error));
None
}
}
}
fn late_initialize(self, error: E);
}
impl TryOrInitialize<repr_c::Box<NsError>> for Option<Out<'_, repr_c::Box<NsError>>> {
type InnerError = NsError;
fn late_initialize(self, error: repr_c::Box<NsError>) {
if let Some(out_error) = self {
out_error.write(error);
}
}
}