| David Tolnay | 1e54817 | 2020-03-16 13:37:09 -0700 | [diff] [blame^] | 1 | use crate::rust_str::RustStr; |
| 2 | use std::fmt::Display; |
| 3 | use std::ptr; |
| 4 | use std::slice; |
| 5 | use std::str; |
| 6 | |
| 7 | pub unsafe fn r#try<T, E>(ret: *mut T, result: Result<T, E>) -> Option<RustStr> |
| 8 | where |
| 9 | E: Display, |
| 10 | { |
| 11 | match result { |
| 12 | Ok(ok) => { |
| 13 | ptr::write(ret, ok); |
| 14 | None |
| 15 | } |
| 16 | Err(err) => Some(to_c_string(err.to_string())), |
| 17 | } |
| 18 | } |
| 19 | |
| 20 | unsafe fn to_c_string(msg: String) -> RustStr { |
| 21 | let mut msg = msg; |
| 22 | msg.as_mut_vec().push(b'\0'); |
| 23 | let ptr = msg.as_ptr(); |
| 24 | let len = msg.len(); |
| 25 | |
| 26 | extern "C" { |
| 27 | #[link_name = "cxxbridge02$error"] |
| 28 | fn error(ptr: *const u8, len: usize) -> *const u8; |
| 29 | } |
| 30 | |
| 31 | let copy = error(ptr, len); |
| 32 | let slice = slice::from_raw_parts(copy, len); |
| 33 | let string = str::from_utf8_unchecked(slice); |
| 34 | RustStr::from(string) |
| 35 | } |