use crate::ffi;
use std::os::raw::c_void;
use super::thunks::{key_provider_thunk, password_thunk};
use super::traits::{KeyProvider, PasswordProvider};
pub(crate) struct PasswordHolder {
pub(crate) inner: Box<dyn PasswordProvider>,
}
pub(crate) struct KeyProviderHolder {
pub(crate) inner: Box<dyn KeyProvider>,
}
pub(crate) struct Callbacks {
password: Option<Box<PasswordHolder>>,
key_provider: Option<Box<KeyProviderHolder>>,
}
impl Callbacks {
pub(crate) fn new() -> Self {
Callbacks {
password: None,
key_provider: None,
}
}
pub(crate) fn set_password(
&mut self,
ffi: ffi::rnp_ffi_t,
provider: Box<dyn PasswordProvider>,
) {
let boxed = Box::new(PasswordHolder { inner: provider });
let raw: *mut PasswordHolder = Box::into_raw(boxed);
unsafe {
let _ = ffi::rnp_ffi_set_pass_provider(ffi, Some(password_thunk), raw as *mut c_void);
}
self.password = Some(unsafe { Box::from_raw(raw) });
}
pub(crate) fn set_key_provider(
&mut self,
ffi: ffi::rnp_ffi_t,
provider: Box<dyn KeyProvider>,
) {
let boxed = Box::new(KeyProviderHolder { inner: provider });
let raw: *mut KeyProviderHolder = Box::into_raw(boxed);
unsafe {
let _ = ffi::rnp_ffi_set_key_provider(ffi, Some(key_provider_thunk), raw as *mut c_void);
}
self.key_provider = Some(unsafe { Box::from_raw(raw) });
}
pub(crate) fn take(&mut self) {
self.password.take();
self.key_provider.take();
}
}