1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
use ockam_core::Error;
use std::ffi::CString;
use std::os::raw::c_char;

#[repr(C)]
#[derive(Debug, PartialEq)]
/// Error type relating to FFI specific failures.
pub struct FfiOckamError {
    code: i32,
    domain: *const c_char,
}

impl FfiOckamError {
    /// Create a new error.
    pub fn new(code: i32, domain: &str) -> Self {
        Self {
            code,
            // TODO: Should this graciously fail?
            domain: CString::new(domain.as_bytes()).unwrap().into_raw(),
        }
    }

    /// No error.
    pub fn none() -> Self {
        Self {
            code: 0,
            domain: std::ptr::null(),
        }
    }
}

impl From<Error> for FfiOckamError {
    fn from(err: Error) -> Self {
        // TODO: Should this graciously fail?
        let heaped = CString::new(err.domain().as_bytes()).unwrap();

        // Past this point C is responsible for freeing up its memory!
        Self {
            code: err.code() as i32,
            domain: heaped.into_raw(),
        }
    }
}

/// Represents the failures that can occur in an Ockam FFI Vault.
#[derive(Clone, Copy, Debug)]
pub enum FfiError {
    /// No error.
    None,

    /// Persistence is not supported for this Vault implementation.
    VaultDoesntSupportPersistence,

    /// An underlying filesystem error prevented Vault creation.
    ErrorCreatingFilesystemVault,

    /// Invalid parameter.
    InvalidParam,

    /// Entry not found.
    EntryNotFound,

    /// Unknown public key type.
    UnknownPublicKeyType,

    /// Invalid string.
    InvalidString,

    /// Buffer is too small.
    BufferTooSmall,

    /// A public key is invalid.
    InvalidPublicKey,

    /// No such Vault.
    VaultNotFound,

    /// Ownership error.
    OwnershipError,
}

impl FfiError {
    /// Integer code associated with the error domain.
    pub const DOMAIN_CODE: u32 = 13_000;
    /// Descriptive name for the error domain.
    pub const DOMAIN_NAME: &'static str = "OCKAM_FFI";
}

impl From<FfiError> for Error {
    fn from(err: FfiError) -> Self {
        Self::new(FfiError::DOMAIN_CODE + (err as u32), FfiError::DOMAIN_NAME)
    }
}

impl From<FfiError> for FfiOckamError {
    fn from(err: FfiError) -> Self {
        let err: Error = err.into();
        Self::from(err)
    }
}