use crate::{
c_api::i32_to_bool,
error::{PdfiumError, PdfiumResult},
lib, pdfium_constants,
pdfium_types::{FPDF_SCHHANDLE, Handle, SearchHandle},
};
use bitflags::bitflags;
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PdfiumSearchFlags: i32 {
const MATCH_CASE = pdfium_constants::FPDF_MATCHCASE;
const MATCH_WHOLE_WORD = pdfium_constants::FPDF_MATCHWHOLEWORD;
const CONSECUTIVE = pdfium_constants::FPDF_CONSECUTIVE;
}
}
#[derive(Debug, Clone)]
pub struct PdfiumSearch {
handle: SearchHandle,
}
impl PdfiumSearch {
pub(crate) fn new_from_handle(handle: FPDF_SCHHANDLE) -> PdfiumResult<Self> {
if handle.is_null() {
Err(PdfiumError::NullHandle)
} else {
Ok(Self {
handle: Handle::new(handle, Some(close_search)),
})
}
}
pub fn find_next(&self) -> bool {
i32_to_bool(lib().FPDFText_FindNext(self))
}
pub fn find_prev(&self) -> bool {
i32_to_bool(lib().FPDFText_FindPrev(self))
}
pub fn get_count(&self) -> i32 {
lib().FPDFText_GetSchCount(self)
}
pub fn get_index(&self) -> i32 {
lib().FPDFText_GetSchResultIndex(self)
}
}
impl From<&PdfiumSearch> for FPDF_SCHHANDLE {
fn from(search: &PdfiumSearch) -> Self {
search.handle.handle()
}
}
fn close_search(search: FPDF_SCHHANDLE) {
lib().FPDFText_FindClose(search);
}
pub struct PdfiumSearchResult {
index: i32,
count: i32,
}
impl PdfiumSearchResult {
pub fn index(&self) -> i32 {
self.index
}
pub fn count(&self) -> i32 {
self.count
}
}
pub struct PdfiumSearchIterator {
pub(crate) inner: PdfiumResult<PdfiumSearch>,
}
impl Iterator for PdfiumSearchIterator {
type Item = PdfiumSearchResult;
fn next(&mut self) -> Option<Self::Item> {
match &self.inner {
Ok(search) => {
if search.find_next() {
Some(PdfiumSearchResult {
index: search.get_index(),
count: search.get_count(),
})
} else {
None
}
}
Err(_) => None,
}
}
}