|
10 | 10 | //! - `vrp-core` crate implements default metaheuristic |
11 | 11 |
|
12 | 12 | #![warn(missing_docs)] |
| 13 | +#![deny(unsafe_code)] // NOTE: use deny instead forbid as we need allow unsafe code for c_interop |
13 | 14 |
|
14 | 15 | #[cfg(test)] |
15 | 16 | #[path = "../tests/helpers/mod.rs"] |
@@ -45,6 +46,7 @@ use vrp_pragmatic::get_unique_locations; |
45 | 46 | use vrp_pragmatic::validation::ValidationContext; |
46 | 47 |
|
47 | 48 | #[cfg(not(target_arch = "wasm32"))] |
| 49 | +#[allow(unsafe_code)] |
48 | 50 | mod c_interop { |
49 | 51 | use super::*; |
50 | 52 | use crate::extensions::solve::config::read_config; |
@@ -110,22 +112,22 @@ mod c_interop { |
110 | 112 | extern "C" fn convert_to_pragmatic( |
111 | 113 | format: *const c_char, |
112 | 114 | inputs: *const *const c_char, |
113 | | - input_len: *const i32, |
| 115 | + input_len: usize, |
114 | 116 | success: Callback, |
115 | 117 | failure: Callback, |
116 | 118 | ) { |
117 | 119 | catch_panic(failure, || { |
118 | 120 | let format = to_string(format); |
119 | | - let inputs = unsafe { slice::from_raw_parts(inputs, input_len as usize).to_vec() }; |
| 121 | + let inputs = unsafe { slice::from_raw_parts(inputs, input_len).to_vec() }; |
120 | 122 | let inputs = inputs.iter().map(|p| to_string(*p)).collect::<Vec<_>>(); |
121 | 123 | let readers = inputs.iter().map(|p| BufReader::new(p.as_bytes())).collect::<Vec<_>>(); |
122 | 124 |
|
123 | 125 | match import_problem(format.as_str(), Some(readers)) { |
124 | 126 | Ok(problem) => { |
125 | | - let mut buffer = String::new(); |
126 | | - let writer = unsafe { BufWriter::new(buffer.as_mut_vec()) }; |
127 | | - serialize_problem(writer, &problem).unwrap(); |
128 | | - let problem = CString::new(buffer.as_bytes()).unwrap(); |
| 127 | + let mut writer = BufWriter::new(Vec::new()); |
| 128 | + serialize_problem(&problem, &mut writer).unwrap(); |
| 129 | + let bytes = writer.into_inner().expect("cannot use writer"); |
| 130 | + let problem = CString::new(bytes).unwrap(); |
129 | 131 |
|
130 | 132 | success(problem.as_ptr()); |
131 | 133 | } |
@@ -351,11 +353,14 @@ mod py_interop { |
351 | 353 | fn convert_to_pragmatic(format: &str, inputs: Vec<String>) -> PyResult<String> { |
352 | 354 | let readers = inputs.iter().map(|p| BufReader::new(p.as_bytes())).collect::<Vec<_>>(); |
353 | 355 | import_problem(format, Some(readers)) |
354 | | - .map(|problem| { |
355 | | - let mut buffer = String::new(); |
356 | | - serialize_problem(unsafe { BufWriter::new(buffer.as_mut_vec()) }, &problem).unwrap(); |
| 356 | + .and_then(|problem| { |
| 357 | + let mut writer = BufWriter::new(Vec::new()); |
| 358 | + serialize_problem(&problem, &mut writer).unwrap(); |
357 | 359 |
|
358 | | - buffer |
| 360 | + writer |
| 361 | + .into_inner() |
| 362 | + .map_err(|err| format!("BufWriter: {err}")) |
| 363 | + .and_then(|bytes| String::from_utf8(bytes).map_err(|err| format!("StringUTF8: {err}"))) |
359 | 364 | }) |
360 | 365 | .map_err(PyOSError::new_err) |
361 | 366 | } |
@@ -458,11 +463,13 @@ mod wasm { |
458 | 463 |
|
459 | 464 | match import_problem(format, Some(readers)) { |
460 | 465 | Ok(problem) => { |
461 | | - let mut buffer = String::new(); |
462 | | - let writer = unsafe { BufWriter::new(buffer.as_mut_vec()) }; |
463 | | - serialize_problem(writer, &problem).unwrap(); |
| 466 | + let mut writer = BufWriter::new(Vec::new()); |
| 467 | + serialize_problem(&problem, &mut writer).unwrap(); |
| 468 | + |
| 469 | + let bytes = writer.into_inner().unwrap(); |
| 470 | + let result = String::from_utf8(bytes).unwrap(); |
464 | 471 |
|
465 | | - Ok(JsValue::from_str(buffer.as_str())) |
| 472 | + Ok(JsValue::from_str(result.as_str())) |
466 | 473 | } |
467 | 474 | Err(err) => Err(JsValue::from_str(err.to_string().as_str())), |
468 | 475 | } |
|
0 commit comments