1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use ffi_convert::{CReprOf, RawPointerConverter};
use std::ffi::CString;

use rustfst::semirings::TropicalWeight;
use rustfst::{Semiring, StringPath};

use crate::{get, wrap, RUSTFST_FFI_RESULT};

#[derive(RawPointerConverter)]
pub struct CStringPath(pub(crate) StringPath<TropicalWeight>);

/// # Safety
///
/// The pointers should be valid.
#[no_mangle]
pub unsafe extern "C" fn string_path_destroy(iter_ptr: *mut CStringPath) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        if iter_ptr.is_null() {
            return Ok(());
        }

        unsafe { drop(Box::from_raw(iter_ptr)) }
        Ok(())
    })
}

/// # Safety
///
/// The pointers should be valid.
#[no_mangle]
pub unsafe extern "C" fn string_path_weight(
    c_string_path: *const CStringPath,
    weight: *mut libc::c_float,
) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        let string_path = get!(CStringPath, c_string_path);
        let weight_val = *string_path.weight().value();
        unsafe { *weight = weight_val }
        Ok(())
    })
}

/// # Safety
///
/// The pointers should be valid.
#[no_mangle]
pub unsafe extern "C" fn string_path_istring(
    c_string_path: *const CStringPath,
    c_istring: *mut *const libc::c_char,
) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        let string_path = get!(CStringPath, c_string_path);
        let istring = string_path.istring()?;
        unsafe {
            *c_istring = CString::c_repr_of(istring)?.into_raw_pointer() as *const libc::c_char
        }

        Ok(())
    })
}

/// # Safety
///
/// The pointers should be valid.
#[no_mangle]
pub unsafe extern "C" fn string_path_ostring(
    c_string_path: *const CStringPath,
    c_ostring: *mut *const libc::c_char,
) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        let string_path = get!(CStringPath, c_string_path);
        let ostring = string_path.ostring()?;
        unsafe {
            *c_ostring = CString::c_repr_of(ostring)?.into_raw_pointer() as *const libc::c_char
        }

        Ok(())
    })
}