rustfst_ffi/
string_paths_iterator.rs1use std::iter::Peekable;
2
3use anyhow::{anyhow, Result};
4use ffi_convert::{RawPointerConverter, UnexpectedNullPointerError};
5
6use rustfst::fst_impls::VectorFst;
7use rustfst::prelude::{Fst, StringPathsIterator};
8use rustfst::semirings::TropicalWeight;
9
10use crate::fst::as_fst;
11use crate::fst::CFst;
12use crate::string_path::CStringPath;
13use crate::{get, get_mut, wrap, RUSTFST_FFI_RESULT};
14
15pub struct CStringPathsIterator<'a>(
16 pub(crate) Peekable<StringPathsIterator<'a, TropicalWeight, VectorFst<TropicalWeight>>>,
17);
18
19impl<'a> RawPointerConverter<CStringPathsIterator<'a>> for CStringPathsIterator<'a> {
20 fn into_raw_pointer(self) -> *const CStringPathsIterator<'a> {
21 Box::into_raw(Box::new(self)) as _
22 }
23 fn into_raw_pointer_mut(self) -> *mut CStringPathsIterator<'a> {
24 Box::into_raw(Box::new(self))
25 }
26
27 unsafe fn from_raw_pointer(
28 input: *const CStringPathsIterator<'a>,
29 ) -> Result<Self, UnexpectedNullPointerError> {
30 if input.is_null() {
31 Err(UnexpectedNullPointerError)
32 } else {
33 Ok(*Box::from_raw(input as _))
34 }
35 }
36
37 unsafe fn from_raw_pointer_mut(
38 input: *mut CStringPathsIterator<'a>,
39 ) -> Result<Self, UnexpectedNullPointerError> {
40 if input.is_null() {
41 Err(UnexpectedNullPointerError)
42 } else {
43 Ok(*Box::from_raw(input))
44 }
45 }
46}
47
48#[no_mangle]
52pub unsafe extern "C" fn string_paths_iterator_new(
53 fst: *const CFst,
54 res_iterator: *mut *const CStringPathsIterator,
55) -> RUSTFST_FFI_RESULT {
56 wrap(|| {
57 let fst = get!(CFst, fst);
58 let fst: &VectorFst<_> = as_fst!(VectorFst<TropicalWeight>, fst);
59 let it = fst.string_paths_iter()?.peekable();
60 let raw_pointer = CStringPathsIterator(it).into_raw_pointer();
61 unsafe { *res_iterator = raw_pointer };
62 Ok(())
63 })
64}
65
66#[no_mangle]
70pub unsafe extern "C" fn string_paths_iterator_next(
71 iter_ptr: *mut CStringPathsIterator,
72 string_path_ptr: *mut *const CStringPath,
73) -> RUSTFST_FFI_RESULT {
74 wrap(|| {
75 let string_paths_iter = get_mut!(CStringPathsIterator, iter_ptr);
76 string_paths_iter
77 .next()
78 .map(|string_path| {
79 let ctr = CStringPath(string_path).into_raw_pointer();
80 unsafe { *string_path_ptr = ctr };
81 Ok(())
82 })
83 .unwrap_or_else(|| -> Result<()> {
84 unsafe { *string_path_ptr = std::ptr::null_mut() };
85 Ok(())
86 })?;
87 Ok(())
88 })
89}
90
91#[no_mangle]
95pub unsafe extern "C" fn string_paths_iterator_done(
96 iter_ptr: *mut CStringPathsIterator,
97 done: *mut libc::size_t,
98) -> RUSTFST_FFI_RESULT {
99 wrap(|| {
100 let string_paths_iter = get_mut!(CStringPathsIterator, iter_ptr);
101 let res = string_paths_iter.peek().is_none();
102 unsafe { *done = res as libc::size_t };
103 Ok(())
104 })
105}
106
107#[no_mangle]
111pub unsafe extern "C" fn string_paths_iterator_destroy(
112 iter_ptr: *mut CStringPathsIterator,
113) -> RUSTFST_FFI_RESULT {
114 wrap(|| {
115 if iter_ptr.is_null() {
116 return Ok(());
117 }
118
119 drop(unsafe { Box::from_raw(iter_ptr) });
120 Ok(())
121 })
122}