use crate::error::{self, check, Result};
use crate::ffi;
use crate::ffi_safe::{call_for_bool, call_for_u32, call_for_usize};
use std::marker::PhantomData;
use std::ptr;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UidType {
UserId,
UserAttr,
Other(u32),
}
impl UidType {
pub(crate) fn from_raw(raw: u32) -> Self {
let user_id = ffi::RNP_USER_ID as u32;
let user_attr = ffi::RNP_USER_ATTR as u32;
if raw == user_id {
UidType::UserId
} else if raw == user_attr {
UidType::UserAttr
} else {
UidType::Other(raw)
}
}
}
pub struct Uid<'key> {
pub(crate) handle: ffi::rnp_uid_handle_t,
_key: PhantomData<&'key crate::Key<'key>>,
}
impl<'key> Uid<'key> {
pub(crate) fn from_handle(handle: ffi::rnp_uid_handle_t) -> Self {
Uid {
handle,
_key: PhantomData,
}
}
pub fn uid_type(&self) -> Result<UidType> {
let raw = call_for_u32(|out| unsafe { ffi::rnp_uid_get_type(self.handle, out) })?;
Ok(UidType::from_raw(raw))
}
pub fn data(&self) -> Result<Vec<u8>> {
let mut ptr: *mut std::os::raw::c_void = ptr::null_mut();
let mut len: usize = 0;
unsafe {
check(ffi::rnp_uid_get_data(self.handle, &mut ptr, &mut len))?;
if ptr.is_null() {
return Ok(Vec::new());
}
let v = std::slice::from_raw_parts(ptr as *const u8, len).to_vec();
ffi::rnp_buffer_destroy(ptr);
Ok(v)
}
}
pub fn data_string(&self) -> Result<String> {
let bytes = self.data()?;
Ok(String::from_utf8_lossy(&bytes).into_owned())
}
pub fn is_primary(&self) -> Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_uid_is_primary(self.handle, out) })
}
pub fn is_valid(&self) -> Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_uid_is_valid(self.handle, out) })
}
pub fn is_revoked(&self) -> Result<bool> {
call_for_bool(|out| unsafe { ffi::rnp_uid_is_revoked(self.handle, out) })
}
pub fn signature_count(&self) -> Result<usize> {
call_for_usize(|out| unsafe { ffi::rnp_uid_get_signature_count(self.handle, out) })
}
pub fn signature_at(&self, idx: usize) -> Result<Option<crate::Signature<'_>>> {
let mut handle: ffi::rnp_signature_handle_t = ptr::null_mut();
unsafe {
check(ffi::rnp_uid_get_signature_at(self.handle, idx, &mut handle))?;
}
if handle.is_null() {
Ok(None)
} else {
Ok(Some(crate::Signature::from_handle(handle)))
}
}
pub fn signatures(&self) -> Result<Vec<crate::Signature<'_>>> {
let n = self.signature_count()?;
(0..n)
.map(|i| self.signature_at(i)?.ok_or(error::Error::NullPointer))
.collect()
}
pub fn revocation_signature(&self) -> Result<Option<crate::Signature<'_>>> {
let mut handle: ffi::rnp_signature_handle_t = ptr::null_mut();
unsafe {
check(ffi::rnp_uid_get_revocation_signature(self.handle, &mut handle))?;
}
if handle.is_null() {
Ok(None)
} else {
Ok(Some(crate::Signature::from_handle(handle)))
}
}
pub fn remove(&self, key: &crate::Key<'_>) -> Result<()> {
unsafe { check(ffi::rnp_uid_remove(key.handle, self.handle)) }
}
}
impl<'key> Drop for Uid<'key> {
fn drop(&mut self) {
if !self.handle.is_null() {
unsafe {
let _ = ffi::rnp_uid_handle_destroy(self.handle);
}
self.handle = ptr::null_mut();
}
}
}
#[allow(unused_imports)]
use error as _error_alias;