use std::{ ffi::{CStr, CString, c_char}, ptr::null_mut, }; use llvm_sys::error::LLVMDisposeErrorMessage; pub fn into_cstring>(value: T) -> CString { let string = value.into(); unsafe { CString::from_vec_with_nul_unchecked((string + "\0").into_bytes()) } } pub fn from_cstring(pointer: *mut c_char) -> Option { if pointer.is_null() { None } else { unsafe { CStr::from_ptr(pointer).to_str().ok().map(|s| s.to_owned()) } } } fn cstring_to_err(value: *mut c_char) -> Result<(), String> { from_cstring(value) .filter(|s| !s.is_empty()) .map_or(Ok(()), |s| Err(s)) } pub struct ErrorMessageHolder(*mut c_char); impl ErrorMessageHolder { pub fn null() -> Self { ErrorMessageHolder(null_mut()) } pub fn borrow_mut(&mut self) -> *mut *mut c_char { &mut self.0 } pub fn into_result(&self) -> Result<(), String> { cstring_to_err(self.0) } } impl Drop for ErrorMessageHolder { fn drop(&mut self) { unsafe { if !self.0.is_null() { LLVMDisposeErrorMessage(self.0); } } } }