postagger/
lib.rs

1mod perceptron_tagger;
2pub use self::perceptron_tagger::PerceptronTagger;
3
4mod c_binding {
5
6    use std::ffi::{ CStr , c_char , c_float , CString } ;
7    use crate::perceptron_tagger::PerceptronTagger; 
8
9    #[repr(C)]
10    pub struct CTag {
11        word: *const u8 , 
12        tag: *const u8 , 
13        conf: c_float ,
14    }
15
16    #[repr(C)]
17    pub struct TagResults {
18        tags: *const CTag , 
19        num_tags: usize
20    } 
21
22    unsafe fn get_str(
23        c_char_buffer: *const c_char
24    ) -> String {
25        CStr::from_ptr( c_char_buffer )
26              .to_str()
27              .expect( "Could not convert weights_filepath to &str" )
28              .to_owned()
29    }
30
31    #[no_mangle]
32    pub extern "C" fn tagger_create( 
33        weights_filepath: *const c_char , 
34        classes_filepath: *const c_char , 
35        tags_filepath: *const c_char 
36    ) -> *mut PerceptronTagger  {
37        unsafe {
38            let fp_weights = get_str( weights_filepath )  ;
39            let fp_tags = get_str( tags_filepath ) ; 
40            let fp_classes = get_str( classes_filepath ) ;                
41            Box::into_raw( 
42                Box::new( 
43                    PerceptronTagger::new( fp_weights.as_str() , fp_classes.as_str() , fp_tags.as_str() ) 
44                ) 
45            ) 
46        }
47    }
48
49    #[no_mangle]
50    pub extern "C" fn tagger_annotate(
51        tagger_ptr: *mut PerceptronTagger , 
52        sentence: *const c_char
53    ) -> *const TagResults {
54        unsafe {
55            let tagger = &*tagger_ptr ; 
56            let sentence = get_str( sentence ) ; 
57            let tags: Vec<CTag> = tagger.tag( sentence.as_str() )
58                .iter()
59                .map( |x| {
60                        let word = CString::new( x.word ).expect( "Could not create CString") ; 
61                        let word_ptr = word.as_ptr() ; 
62                        let tag = CString::new( x.tag.as_str() ).expect( "Could not create CString" ) ; 
63                        let tag_ptr = tag.as_ptr() ; 
64                        std::mem::forget( word ) ; 
65                        std::mem::forget( tag ) ;
66                        CTag{ 
67                            word: word_ptr.cast::<u8>() , 
68                            tag: tag_ptr.cast::<u8>() , 
69                            conf: x.conf
70                        } 
71                    }
72                ).collect() ; 
73            let num_tags = tags.len() ; 
74            let tags_ptr = tags.as_ptr() ; 
75            std::mem::forget( tags ) ; 
76            Box::into_raw( Box::new( TagResults {
77                tags: tags_ptr, 
78                num_tags
79            } ) )
80        }
81    }
82
83    #[no_mangle]
84    pub extern "C" fn tagger_release(
85        tagger_ptr: *mut PerceptronTagger
86    )  {
87        if tagger_ptr.is_null() {
88            return;
89        }
90        unsafe {
91            let _ptr = Box::from_raw( tagger_ptr ) ; 
92        }
93    }
94
95}
96
97#[cfg(feature="java")]
98mod java_binding {
99
100    extern crate jni ; 
101    use jni::objects::{JClass, JString};
102    use jni::sys::{jfloat,jlong, jstring};
103    use jni::JNIEnv;
104    use crate::perceptron_tagger::PerceptronTagger;
105    use serde_json ; 
106
107    #[no_mangle]
108    pub extern "C" fn  Java_pos_tagger_POSTagger_create<'a>(
109        mut env: JNIEnv<'a> , 
110        _: JClass<'a> , 
111        weights_filepath: JString<'a> , 
112        classes_filepath: JString<'a>  , 
113        tags_filepath: JString<'a> 
114    ) -> jlong {
115        let fp_weights: String = env.get_string( &weights_filepath )
116                                    .expect( "Could not convert weights_filepath to Rust String" )
117                                    .into() ; 
118        let fp_classes: String = env.get_string( &classes_filepath )
119                                .expect( "Could not convert classes_filepath to Rust String" )
120                                .into() ; 
121        let fp_tags: String = env.get_string( &tags_filepath )
122                            .expect( "Could not convert tags_filepath to Rust String" )
123                            .into() ; 
124        Box::into_raw(
125            Box::new( 
126                PerceptronTagger::new( fp_weights.as_str() , fp_classes.as_str() , fp_tags.as_str() ) 
127            )
128        ) as jlong
129    }
130
131    #[no_mangle]
132    pub extern "C" fn Java_pos_tagger_POSTagger_annotate<'a>(
133        mut env: JNIEnv<'a>,
134        _: JClass<'a>,
135        instance_ptr: jlong,
136        sentence: JString<'a>
137    ) -> JString<'a> {
138        let instance = unsafe { &mut *(instance_ptr as *mut PerceptronTagger) } ; 
139        let sentence: String = env.get_string( &sentence )
140                                  .expect( "Could not convert sentence to Rust String" )
141                                  .into() ; 
142        let tags = instance.tag( sentence.as_str() ) ;
143        let tags_json_str = serde_json::to_string( &tags ).expect( "Could not convert tags to JSON" ) ; 
144        env.new_string( tags_json_str ).expect( "Could not convert tags_json_str to jstring" )
145    }
146
147    #[no_mangle]
148    pub extern "C" fn Java_pos_tagger_POSTagger_release(
149        _: JNIEnv,
150        _: JClass,
151        instance_ptr: jlong,
152    ) {
153        let _ptr = unsafe { Box::from_raw( instance_ptr as *mut PerceptronTagger) };
154    }
155
156}