use crate::callbacks::Callbacks;
use crate::error::{self, check, Result};
use crate::ffi;
use std::ffi::CString;
use std::ptr;
pub struct Context {
pub(crate) ffi: ffi::rnp_ffi_t,
pub(crate) callbacks: Callbacks,
}
impl Context {
pub fn new() -> Result<Self> {
Self::with_format(KeyringFormat::Gpg, KeyringFormat::Gpg)
}
pub fn with_format(
pub_format: KeyringFormat,
sec_format: KeyringFormat,
) -> Result<Self> {
let pub_c = CString::new(pub_format.as_str()).unwrap();
let sec_c = CString::new(sec_format.as_str()).unwrap();
let mut ffi_h: ffi::rnp_ffi_t = ptr::null_mut();
unsafe {
check(ffi::rnp_ffi_create(
&mut ffi_h,
pub_c.as_ptr(),
sec_c.as_ptr(),
))?;
}
if ffi_h.is_null() {
return Err(error::Error::NullPointer);
}
Ok(Context {
ffi: ffi_h,
callbacks: Callbacks::new(),
})
}
pub fn set_password_provider(
&mut self,
provider: Box<dyn crate::callbacks::PasswordProvider>,
) {
self.callbacks.set_password(self.ffi, provider);
}
pub fn set_key_provider(&mut self, provider: Box<dyn crate::callbacks::KeyProvider>) {
self.callbacks.set_key_provider(self.ffi, provider);
}
}
impl Drop for Context {
fn drop(&mut self) {
self.callbacks.take();
if !self.ffi.is_null() {
unsafe {
let _ = ffi::rnp_ffi_destroy(self.ffi);
}
self.ffi = ptr::null_mut();
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum KeyringFormat {
Gpg,
Kbx,
G10,
Json,
}
impl KeyringFormat {
pub fn as_str(self) -> &'static str {
match self {
KeyringFormat::Gpg => "GPG",
KeyringFormat::Kbx => "KBX",
KeyringFormat::G10 => "G10",
KeyringFormat::Json => "JSON",
}
}
}