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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use crate::tr::CTr;
use crate::{get, get_mut, wrap, RUSTFST_FFI_RESULT};
use std::ffi::CString;

use anyhow::Result;
use ffi_convert::*;
use rustfst::prelude::TrsVec;
use rustfst::semirings::TropicalWeight;
use rustfst::Trs;

#[derive(RawPointerConverter)]
pub struct CTrs(pub(crate) TrsVec<TropicalWeight>);

#[no_mangle]
pub extern "C" fn trs_vec_new(new_struct: *mut *const CTrs) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        let trs: TrsVec<TropicalWeight> = TrsVec::default();
        let raw_pointer = CTrs(trs).into_raw_pointer();
        unsafe { *new_struct = raw_pointer };
        Ok(())
    })
}

#[no_mangle]
pub extern "C" fn trs_vec_remove(
    trs: *mut CTrs,
    index: libc::size_t,
    removed_tr_ptr: *mut *const CTr,
) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        let trs = get_mut!(CTrs, trs);
        let removed_tr = trs.remove(index);
        let ctr = Box::into_raw(Box::new(CTr::c_repr_of(removed_tr)?));
        unsafe { *removed_tr_ptr = ctr };
        Ok(())
    })
}

#[no_mangle]
pub extern "C" fn trs_vec_push(trs: *mut CTrs, new_tr: *const CTr) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        let trs = get_mut!(CTrs, trs);
        let tr = unsafe { <CTr as ffi_convert::RawBorrow<CTr>>::raw_borrow(new_tr)? };
        trs.push(tr.as_rust()?);
        Ok(())
    })
}

#[no_mangle]
pub extern "C" fn trs_vec_shallow_clone(
    trs: *const CTrs,
    cloned_trs_ptr: *mut *const CTrs,
) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        let trs = get!(CTrs, trs);
        let cloned_trs = trs.shallow_clone();
        let raw_pointer = CTrs(cloned_trs).into_raw_pointer();
        unsafe { *cloned_trs_ptr = raw_pointer };
        Ok(())
    })
}

#[no_mangle]
pub extern "C" fn trs_vec_len(trs: *const CTrs, num_trs: *mut libc::size_t) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        let trs = get!(CTrs, trs);
        unsafe { *num_trs = trs.len() as libc::size_t };
        Ok(())
    })
}

#[no_mangle]
pub extern "C" fn trs_vec_display(
    trs: *const CTrs,
    string: *mut *const libc::c_char,
) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        let trs = get!(CTrs, trs);
        let trs_display = format!("{:?}", trs);
        unsafe {
            *string = CString::c_repr_of(trs_display)?.into_raw_pointer() as *const libc::c_char
        };
        Ok(())
    })
}

#[no_mangle]
pub extern "C" fn trs_vec_delete(trs_ptr: *mut CTrs) -> RUSTFST_FFI_RESULT {
    wrap(|| {
        if trs_ptr.is_null() {
            return Ok(());
        }

        unsafe {
            Box::from_raw(trs_ptr);
        }
        Ok(())
    })
}