use crate::{
PdfiumDestination, PdfiumDocument,
error::{PdfiumError, PdfiumResult},
lib,
pdfium_types::{ActionHandle, FPDF_ACTION, Handle},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum PdfiumActionType {
#[default]
Unsupported,
Goto,
RemoteGoto,
#[allow(clippy::upper_case_acronyms)] URI,
Launch,
EmbeddedGoto,
}
#[derive(Debug, Clone)]
pub struct PdfiumAction {
handle: ActionHandle,
}
impl PdfiumAction {
pub(crate) fn new_from_handle(handle: FPDF_ACTION) -> PdfiumResult<Self> {
if handle.is_null() {
Err(PdfiumError::NullHandle)
} else {
Ok(Self {
handle: Handle::new(handle, None), })
}
}
pub fn r#type(&self) -> PdfiumActionType {
match lib().FPDFAction_GetType(self) {
0 => PdfiumActionType::Unsupported,
1 => PdfiumActionType::Goto,
2 => PdfiumActionType::RemoteGoto,
3 => PdfiumActionType::URI,
4 => PdfiumActionType::Launch,
5 => PdfiumActionType::EmbeddedGoto,
_ => PdfiumActionType::Unsupported,
}
}
pub fn dest(&self, document: &PdfiumDocument) -> PdfiumResult<PdfiumDestination> {
lib().FPDFAction_GetDest(document, self)
}
pub fn file_path(&self) -> PdfiumResult<String> {
let lib = lib();
let buf_len = lib.FPDFAction_GetFilePath(self, None, 0);
if buf_len == 0 {
return Err(PdfiumError::InvokationFailed);
}
let mut buffer = vec![0u8; buf_len as usize];
let actual_len = lib.FPDFAction_GetFilePath(self, Some(&mut buffer), buf_len);
if actual_len == 0 {
return Err(PdfiumError::InvokationFailed);
}
let content_len = (actual_len as usize).saturating_sub(1);
buffer.truncate(content_len);
Ok(String::from_utf8_lossy(&buffer).into_owned())
}
pub fn uri_path(&self, doc: &PdfiumDocument) -> PdfiumResult<Vec<u8>> {
let lib = lib();
let buf_len = lib.FPDFAction_GetURIPath(doc, self, None, 0);
if buf_len == 0 {
return Err(PdfiumError::InvokationFailed);
}
let mut buffer = vec![0u8; buf_len as usize];
let actual_len = lib.FPDFAction_GetURIPath(doc, self, Some(&mut buffer), buf_len);
if actual_len == 0 {
return Err(PdfiumError::InvokationFailed);
}
let content_len = (actual_len as usize).saturating_sub(1);
buffer.truncate(content_len); Ok(buffer)
}
}
impl From<&PdfiumAction> for FPDF_ACTION {
fn from(action: &PdfiumAction) -> Self {
action.handle.handle()
}
}