1- use ironcalc:: base:: cell:: CellValue ;
1+ use ironcalc:: base:: cell;
22use ironcalc:: base:: Model ;
33use std:: ffi:: { c_char, CString } ;
44
@@ -10,6 +10,7 @@ pub enum ModelContextErrorTag {
1010 XlsxError = 1 ,
1111 WorkbookError = 2 ,
1212 SetUserInputError = 3 ,
13+ GetUserInputError = 4 ,
1314}
1415
1516#[ repr( C ) ]
@@ -26,21 +27,23 @@ pub struct CreateModelContextResult {
2627 is_ok : bool ,
2728}
2829
29- impl CreateModelContextResult {
30- fn create_error ( message : String , tag : ModelContextErrorTag ) -> CreateModelContextResult {
31- let message_ptr = CString :: new ( message)
32- . expect ( "Couldn't create CString" )
33- . into_raw ( ) ;
30+ fn create_error ( message : String , tag : ModelContextErrorTag ) -> * mut ModelContextError {
31+ let message_ptr = CString :: new ( message)
32+ . expect ( "Couldn't create CString" )
33+ . into_raw ( ) ;
3434
35- let error = Box :: into_raw ( Box :: new ( ModelContextError {
36- tag,
37- has_message : true ,
38- message : message_ptr,
39- } ) ) ;
35+ Box :: into_raw ( Box :: new ( ModelContextError {
36+ tag,
37+ has_message : true ,
38+ message : message_ptr,
39+ } ) )
40+ }
4041
42+ impl CreateModelContextResult {
43+ fn create_error ( message : String , tag : ModelContextErrorTag ) -> CreateModelContextResult {
4144 CreateModelContextResult {
4245 model : std:: ptr:: null_mut ( ) ,
43- error,
46+ error : create_error ( message , tag ) ,
4447 is_ok : false ,
4548 }
4649 }
@@ -141,27 +144,93 @@ pub unsafe extern "C" fn evaluate(context: *mut ModelContext) {
141144 Box :: into_raw ( ctx) as * mut ModelContext ;
142145}
143146
147+ #[ repr( C ) ]
148+ #[ derive( PartialEq ) ]
149+ pub enum CellValueTag {
150+ None = 0 ,
151+ String = 1 ,
152+ Number = 2 ,
153+ Boolean = 3 ,
154+ }
155+
156+ #[ repr( C ) ]
157+ pub struct CellValue {
158+ tag : CellValueTag ,
159+ string_value : * const c_char ,
160+ number_value : f64 ,
161+ boolean_value : bool ,
162+ }
163+
164+ #[ repr( C ) ]
165+ pub struct GetValueResult {
166+ value : * mut CellValue ,
167+ error : * mut ModelContextError ,
168+ is_ok : bool ,
169+ }
170+
144171#[ no_mangle]
145- pub unsafe extern "C" fn get_value (
172+ pub unsafe extern "C" fn get_cell_value_by_index (
146173 context : * mut ModelContext ,
147- sheet : i32 ,
174+ sheet : u32 ,
148175 row : i32 ,
149176 col : i32 ,
150- ) -> i32 {
177+ ) -> GetValueResult {
151178 let ctx = Box :: from_raw ( context as * mut InternalModelContext ) ;
152179
153- let value = ctx
154- . model
155- . get_cell_value_by_index ( sheet as u32 , row, col)
156- . expect ( "couldn't get sheet" ) ;
157- let return_value = match value {
158- CellValue :: Number ( x) => x as i32 ,
159- _ => 0 ,
180+ let value = match ctx. model . get_cell_value_by_index ( sheet, row, col) {
181+ Ok ( value) => value,
182+ Err ( message) => {
183+ let error = create_error ( message, ModelContextErrorTag :: GetUserInputError ) ;
184+ Box :: into_raw ( ctx) as * mut ModelContext ;
185+ return GetValueResult {
186+ value : std:: ptr:: null_mut ( ) ,
187+ error,
188+ is_ok : false ,
189+ } ;
190+ }
191+ } ;
192+
193+ let cell_value = match value {
194+ cell:: CellValue :: Number ( value) => CellValue {
195+ tag : CellValueTag :: Number ,
196+ string_value : Default :: default ( ) ,
197+ number_value : value,
198+ boolean_value : Default :: default ( ) ,
199+ } ,
200+ cell:: CellValue :: None => CellValue {
201+ tag : CellValueTag :: None ,
202+ string_value : Default :: default ( ) ,
203+ number_value : Default :: default ( ) ,
204+ boolean_value : Default :: default ( ) ,
205+ } ,
206+ cell:: CellValue :: Boolean ( value) => CellValue {
207+ tag : CellValueTag :: Boolean ,
208+ string_value : Default :: default ( ) ,
209+ number_value : Default :: default ( ) ,
210+ boolean_value : value,
211+ } ,
212+ cell:: CellValue :: String ( value) => {
213+ let value_ptr = CString :: new ( value)
214+ . expect ( "Couldn't create CString" )
215+ . into_raw ( ) ;
216+ CellValue {
217+ tag : CellValueTag :: String ,
218+ string_value : value_ptr,
219+ number_value : Default :: default ( ) ,
220+ boolean_value : Default :: default ( ) ,
221+ }
222+ }
160223 } ;
161224
225+ let cell_value = Box :: into_raw ( Box :: new ( cell_value) ) ;
226+
162227 Box :: into_raw ( ctx) as * mut ModelContext ;
163228
164- return_value
229+ GetValueResult {
230+ value : cell_value,
231+ error : std:: ptr:: null_mut ( ) ,
232+ is_ok : true ,
233+ }
165234}
166235
167236#[ no_mangle]
@@ -173,21 +242,13 @@ pub unsafe extern "C" fn set_user_input(
173242 value : * const c_char ,
174243) -> * mut ModelContextError {
175244 let mut ctx = Box :: from_raw ( context as * mut InternalModelContext ) ;
176- let value = std:: ffi:: CStr :: from_ptr ( value) . to_string_lossy ( ) . to_string ( ) ;
245+ let value = std:: ffi:: CStr :: from_ptr ( value)
246+ . to_string_lossy ( )
247+ . to_string ( ) ;
177248
178249 if let Err ( message) = ctx. model . set_user_input ( sheet, row, col, value) {
179- let message_ptr = CString :: new ( message)
180- . expect ( "Couldn't create CString" )
181- . into_raw ( ) ;
182-
183- let error = Box :: into_raw ( Box :: new ( ModelContextError {
184- tag : ModelContextErrorTag :: SetUserInputError ,
185- has_message : true ,
186- message : message_ptr,
187- } ) ) ;
188-
250+ let error = create_error ( message, ModelContextErrorTag :: SetUserInputError ) ;
189251 Box :: into_raw ( ctx) as * mut ModelContext ;
190-
191252 return error;
192253 }
193254
@@ -196,6 +257,15 @@ pub unsafe extern "C" fn set_user_input(
196257 std:: ptr:: null_mut ( )
197258}
198259
260+ #[ no_mangle]
261+ pub unsafe extern "C" fn dispose_cell_value ( value : * mut CellValue ) {
262+ let value = Box :: from_raw ( value) ;
263+ if value. tag == CellValueTag :: String {
264+ let str = value. string_value as * mut c_char ;
265+ _ = CString :: from_raw ( str)
266+ }
267+ }
268+
199269#[ no_mangle]
200270pub unsafe extern "C" fn dispose_error ( error : * mut ModelContextError ) {
201271 let error = Box :: from_raw ( error) ;
0 commit comments