133d722a9Sopenharmony_ci#![cfg(feature = "alloc")] 233d722a9Sopenharmony_ci#![allow(missing_docs)] 333d722a9Sopenharmony_ci 433d722a9Sopenharmony_ciuse crate::exception::Exception; 533d722a9Sopenharmony_ciuse alloc::boxed::Box; 633d722a9Sopenharmony_ciuse alloc::string::{String, ToString}; 733d722a9Sopenharmony_ciuse core::fmt::Display; 833d722a9Sopenharmony_ciuse core::ptr::{self, NonNull}; 933d722a9Sopenharmony_ciuse core::result::Result as StdResult; 1033d722a9Sopenharmony_ciuse core::slice; 1133d722a9Sopenharmony_ciuse core::str; 1233d722a9Sopenharmony_ci 1333d722a9Sopenharmony_ci#[repr(C)] 1433d722a9Sopenharmony_ci#[derive(Copy, Clone)] 1533d722a9Sopenharmony_cipub struct PtrLen { 1633d722a9Sopenharmony_ci pub ptr: NonNull<u8>, 1733d722a9Sopenharmony_ci pub len: usize, 1833d722a9Sopenharmony_ci} 1933d722a9Sopenharmony_ci 2033d722a9Sopenharmony_ci#[repr(C)] 2133d722a9Sopenharmony_cipub union Result { 2233d722a9Sopenharmony_ci err: PtrLen, 2333d722a9Sopenharmony_ci ok: *const u8, // null 2433d722a9Sopenharmony_ci} 2533d722a9Sopenharmony_ci 2633d722a9Sopenharmony_cipub unsafe fn r#try<T, E>(ret: *mut T, result: StdResult<T, E>) -> Result 2733d722a9Sopenharmony_ciwhere 2833d722a9Sopenharmony_ci E: Display, 2933d722a9Sopenharmony_ci{ 3033d722a9Sopenharmony_ci match result { 3133d722a9Sopenharmony_ci Ok(ok) => { 3233d722a9Sopenharmony_ci unsafe { ptr::write(ret, ok) } 3333d722a9Sopenharmony_ci Result { ok: ptr::null() } 3433d722a9Sopenharmony_ci } 3533d722a9Sopenharmony_ci Err(err) => unsafe { to_c_error(err.to_string()) }, 3633d722a9Sopenharmony_ci } 3733d722a9Sopenharmony_ci} 3833d722a9Sopenharmony_ci 3933d722a9Sopenharmony_ciunsafe fn to_c_error(msg: String) -> Result { 4033d722a9Sopenharmony_ci let mut msg = msg; 4133d722a9Sopenharmony_ci unsafe { msg.as_mut_vec() }.push(b'\0'); 4233d722a9Sopenharmony_ci let ptr = msg.as_ptr(); 4333d722a9Sopenharmony_ci let len = msg.len(); 4433d722a9Sopenharmony_ci 4533d722a9Sopenharmony_ci extern "C" { 4633d722a9Sopenharmony_ci #[link_name = "cxxbridge1$error"] 4733d722a9Sopenharmony_ci fn error(ptr: *const u8, len: usize) -> NonNull<u8>; 4833d722a9Sopenharmony_ci } 4933d722a9Sopenharmony_ci 5033d722a9Sopenharmony_ci let copy = unsafe { error(ptr, len) }; 5133d722a9Sopenharmony_ci let err = PtrLen { ptr: copy, len }; 5233d722a9Sopenharmony_ci Result { err } 5333d722a9Sopenharmony_ci} 5433d722a9Sopenharmony_ci 5533d722a9Sopenharmony_ciimpl Result { 5633d722a9Sopenharmony_ci pub unsafe fn exception(self) -> StdResult<(), Exception> { 5733d722a9Sopenharmony_ci unsafe { 5833d722a9Sopenharmony_ci if self.ok.is_null() { 5933d722a9Sopenharmony_ci Ok(()) 6033d722a9Sopenharmony_ci } else { 6133d722a9Sopenharmony_ci let err = self.err; 6233d722a9Sopenharmony_ci let slice = slice::from_raw_parts_mut(err.ptr.as_ptr(), err.len); 6333d722a9Sopenharmony_ci let s = str::from_utf8_unchecked_mut(slice); 6433d722a9Sopenharmony_ci Err(Exception { 6533d722a9Sopenharmony_ci what: Box::from_raw(s), 6633d722a9Sopenharmony_ci }) 6733d722a9Sopenharmony_ci } 6833d722a9Sopenharmony_ci } 6933d722a9Sopenharmony_ci } 7033d722a9Sopenharmony_ci} 71