rustfst_ffi/
tr.rs

1use crate::{wrap, CLabel, CStateId, RUSTFST_FFI_RESULT};
2
3use ffi_convert::*;
4use rustfst::prelude::{StateId, Tr};
5use rustfst::semirings::TropicalWeight;
6use rustfst::Semiring;
7
8#[derive(Debug)]
9#[repr(C)]
10#[derive(CReprOf, AsRust, CDrop, RawPointerConverter)]
11#[target_type(Tr::<TropicalWeight>)]
12pub struct CTr {
13    /// Input label.
14    pub ilabel: CLabel,
15    /// Output label.
16    pub olabel: CLabel,
17    /// Weight.
18    pub weight: CTropicalWeight,
19    /// ID of the next state.
20    pub nextstate: CStateId,
21}
22
23#[derive(Debug)]
24#[repr(C)]
25#[derive(CDrop, RawPointerConverter)]
26pub struct CTropicalWeight {
27    value: libc::c_float,
28}
29
30impl CReprOf<TropicalWeight> for CTropicalWeight {
31    fn c_repr_of(input: TropicalWeight) -> Result<Self, CReprOfError> {
32        Ok(Self {
33            value: input.take_value(),
34        })
35    }
36}
37
38impl AsRust<TropicalWeight> for CTropicalWeight {
39    fn as_rust(&self) -> Result<TropicalWeight, AsRustError> {
40        Ok(self.value.into())
41    }
42}
43
44/// # Safety
45///
46/// The pointers should be valid.
47#[no_mangle]
48pub unsafe extern "C" fn tr_new(
49    ilabel: CLabel,
50    olabel: CLabel,
51    weight: libc::c_float,
52    nextstate: CStateId,
53    new_struct: *mut *const CTr,
54) -> RUSTFST_FFI_RESULT {
55    wrap(|| {
56        let tr = CTr {
57            ilabel,
58            olabel,
59            weight: CTropicalWeight { value: weight },
60            nextstate,
61        };
62        let raw_pointer: *mut CTr = Box::into_raw(Box::new(tr));
63        unsafe { *new_struct = raw_pointer };
64        Ok(())
65    })
66}
67
68/// # Safety
69///
70/// The pointers should be valid.
71#[no_mangle]
72pub unsafe extern "C" fn tr_ilabel(tr: *const CTr, ilabel: *mut CLabel) -> RUSTFST_FFI_RESULT {
73    wrap(|| {
74        let tr = unsafe { <CTr as ffi_convert::RawBorrow<CTr>>::raw_borrow(tr)? };
75        let ilabel_val = tr.ilabel;
76        unsafe { *ilabel = ilabel_val }
77        Ok(())
78    })
79}
80
81/// # Safety
82///
83/// The pointers should be valid.
84#[no_mangle]
85pub unsafe extern "C" fn tr_set_ilabel(tr: *mut CTr, ilabel: *const CLabel) -> RUSTFST_FFI_RESULT {
86    wrap(|| {
87        let tr = &mut unsafe { <CTr as ffi_convert::RawBorrowMut<CTr>>::raw_borrow_mut(tr)? };
88        tr.ilabel = ilabel as CLabel;
89        Ok(())
90    })
91}
92
93/// # Safety
94///
95/// The pointers should be valid.
96#[no_mangle]
97pub unsafe extern "C" fn tr_olabel(tr: *const CTr, olabel: *mut CLabel) -> RUSTFST_FFI_RESULT {
98    wrap(|| {
99        let tr = unsafe { <CTr as ffi_convert::RawBorrow<CTr>>::raw_borrow(tr)? };
100        let olabel_val = tr.olabel;
101        unsafe { *olabel = olabel_val }
102        Ok(())
103    })
104}
105
106/// # Safety
107///
108/// The pointers should be valid.
109#[no_mangle]
110pub unsafe extern "C" fn tr_set_olabel(tr: *mut CTr, olabel: *const CLabel) -> RUSTFST_FFI_RESULT {
111    wrap(|| {
112        let tr = &mut unsafe { <CTr as ffi_convert::RawBorrowMut<CTr>>::raw_borrow_mut(tr)? };
113        tr.olabel = olabel as CLabel;
114        Ok(())
115    })
116}
117
118/// # Safety
119///
120/// The pointers should be valid.
121#[no_mangle]
122pub unsafe extern "C" fn tr_weight(
123    tr: *const CTr,
124    weight: *mut libc::c_float,
125) -> RUSTFST_FFI_RESULT {
126    wrap(|| {
127        let tr = unsafe { <CTr as ffi_convert::RawBorrow<CTr>>::raw_borrow(tr)? };
128        let weight_val = *tr.weight.as_rust()?.value();
129        unsafe { *weight = weight_val }
130        Ok(())
131    })
132}
133
134/// # Safety
135///
136/// The pointers should be valid.
137#[no_mangle]
138pub unsafe extern "C" fn tr_set_weight(tr: *mut CTr, weight: libc::c_float) -> RUSTFST_FFI_RESULT {
139    wrap(|| {
140        let tr = &mut unsafe { <CTr as ffi_convert::RawBorrowMut<CTr>>::raw_borrow_mut(tr)? };
141        let tropical_weight = TropicalWeight::new(weight);
142        tr.weight = CTropicalWeight::c_repr_of(tropical_weight)?;
143        Ok(())
144    })
145}
146
147/// # Safety
148///
149/// The pointers should be valid.
150#[no_mangle]
151pub unsafe extern "C" fn tr_next_state(
152    tr: *const CTr,
153    next_state: *mut CStateId,
154) -> RUSTFST_FFI_RESULT {
155    wrap(|| {
156        let tr = unsafe { <CTr as ffi_convert::RawBorrow<CTr>>::raw_borrow(tr)? };
157        let next_state_val = tr.nextstate;
158        unsafe { *next_state = next_state_val }
159        Ok(())
160    })
161}
162
163/// # Safety
164///
165/// The pointers should be valid.
166#[no_mangle]
167pub unsafe extern "C" fn tr_set_next_state(
168    tr: *mut CTr,
169    next_state: *const CStateId,
170) -> RUSTFST_FFI_RESULT {
171    wrap(|| {
172        let tr = &mut unsafe { <CTr as ffi_convert::RawBorrowMut<CTr>>::raw_borrow_mut(tr)? };
173        tr.nextstate = next_state as StateId;
174        Ok(())
175    })
176}
177
178/// # Safety
179///
180/// The pointers should be valid.
181#[no_mangle]
182pub unsafe extern "C" fn tr_delete(tr_ptr: *mut CTr) -> RUSTFST_FFI_RESULT {
183    wrap(|| {
184        if tr_ptr.is_null() {
185            return Ok(());
186        }
187
188        drop(unsafe { Box::from_raw(tr_ptr) });
189        Ok(())
190    })
191}