如何解决Rust 的 readline 包装器
我试图为 Rust 创建一个小的 readline 包装器,但是,它不起作用 - 我试图公开该功能以释放和删除历史项目,以及将历史写入文件。当我调用函数时没有任何反应,即我想删除的条目仍然存在。写入文件功能也不起作用,文件甚至没有被创建或修改。
这是我所做的:
use errno::errno;
use libc::c_void;
use std::{ffi::CString,fmt,path::Path,ptr};
mod ext_readline {
use libc::{c_char,c_int,c_void};
#[repr(C)]
pub struct HistoryEntry {
pub line: *const c_char,pub data: *mut c_void,}
#[link(name = "readline")]
extern "C" {
pub fn remove_history(which: c_int) -> *mut HistoryEntry;
pub fn free_history_entry(entry: *mut HistoryEntry) -> *mut c_void;
pub fn write_history(file: *const c_char) -> c_int;
}
}
pub fn remove<'a>(offset: i32) -> &'a mut ext_readline::HistoryEntry {
unsafe { &mut *ext_readline::remove_history(offset) }
}
pub fn free_entry(entry: &mut ext_readline::HistoryEntry) -> Result<(),*mut c_void> {
unsafe {
let data_ptr = ext_readline::free_history_entry(entry);
if data_ptr.is_null() {
Ok(())
} else {
Err(data_ptr)
}
}
}
pub fn write(path: Option<&Path>) -> Result<i32,HistoryError> {
with_path_ptr(path,|ptr| unsafe {
gen_result(ext_readline::write_history(ptr))
})
}
fn with_path_ptr<F>(path: Option<&Path>,f: F) -> Result<i32,HistoryError>
where
F: Fn(*const i8) -> Result<i32,HistoryError>,{
if let Some(p) = path {
match p.to_str() {
Some(p) => {
if let Ok(cs) = CString::new(p) {
return f(cs.as_ptr());
}
}
None => {
return Err(HistoryError::new(
"History Error","Unable to determine path!",))
}
}
}
f(ptr::null())
}
fn gen_result(res: i32) -> Result<i32,HistoryError> {
if res == 0 {
Ok(res)
} else {
let e = errno();
let code = e.0 as i32;
let out = format!("Error {}: {}",code,e);
Err(HistoryError::new("History Error",&out[..]))
}
}
#[derive(Debug)]
/// Represents an error that has occurred within the History API.
pub struct HistoryError {
desc: String,detail: String,}
impl HistoryError {
/// Create a HistoryError struct from the given description and detail.
pub fn new<T>(desc: &str,detail: T) -> HistoryError
where
T: fmt::Display,{
HistoryError {
desc: String::from(desc),detail: format!("{}",detail),}
}
}
/// Implemented as 'self.desc: self.detail'.
impl fmt::Display for HistoryError {
fn fmt(&self,f: &mut fmt::Formatter) -> fmt::Result {
write!(f,"{}: {}",self.desc,self.detail)
}
}
impl From<::std::ffi::NulError> for HistoryError {
fn from(e: ::std::ffi::NulError) -> HistoryError {
HistoryError::new("NulError",e)
}
}
impl From<::std::str::Utf8Error> for HistoryError {
fn from(e: ::std::str::Utf8Error) -> HistoryError {
HistoryError::new("FromUtf8Error",e)
}
}
impl From<::std::num::ParseIntError> for HistoryError {
fn from(e: ::std::num::ParseIntError) -> HistoryError {
HistoryError::new("ParseIntError",e)
}
}
我该如何解决这个问题?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。