update context.rs
This commit is contained in:
parent
6b1ca1463f
commit
d10a2c8908
3 changed files with 86 additions and 43 deletions
1
TODO.md
1
TODO.md
|
|
@ -1,3 +1,4 @@
|
||||||
- [ ] add NixError::from_nonnull that replaces calls to NonNull::new(...).ok_or(...)
|
- [ ] add NixError::from_nonnull that replaces calls to NonNull::new(...).ok_or(...)
|
||||||
- [ ] replace all `use nixide_sys as sys;` -> `use crate::sys;`
|
- [ ] replace all `use nixide_sys as sys;` -> `use crate::sys;`
|
||||||
- [ ] store NonNull pointers in structs!
|
- [ ] store NonNull pointers in structs!
|
||||||
|
- [ ] improve documentation situation on context.rs
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,27 @@
|
||||||
use std::ffi::{c_char, c_uint, CStr, CString};
|
// XXX: TODO: create wrappers methods to access more than just `info->msg()`
|
||||||
|
// struct ErrorInfo
|
||||||
|
// {
|
||||||
|
// Verbosity level;
|
||||||
|
// HintFmt msg;
|
||||||
|
// std::shared_ptr<const Pos> pos;
|
||||||
|
// std::list<Trace> traces;
|
||||||
|
// /**
|
||||||
|
// * Some messages are generated directly by expressions; notably `builtins.warn`, `abort`, `throw`.
|
||||||
|
// * These may be rendered differently, so that users can distinguish them.
|
||||||
|
// */
|
||||||
|
// bool isFromExpr = false;
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Exit status.
|
||||||
|
// */
|
||||||
|
// unsigned int status = 1;
|
||||||
|
|
||||||
|
// Suggestions suggestions;
|
||||||
|
|
||||||
|
// static std::optional<std::string> programName;
|
||||||
|
// };
|
||||||
|
|
||||||
|
use std::ffi::{c_char, CStr};
|
||||||
use std::ptr::{null_mut, NonNull};
|
use std::ptr::{null_mut, NonNull};
|
||||||
|
|
||||||
use crate::error::NixErrorCode;
|
use crate::error::NixErrorCode;
|
||||||
|
|
@ -8,11 +31,12 @@ use crate::util::bindings::wrap_libnix_string_callback;
|
||||||
// XXX: TODO: change this to a `Result<T, NixError>`
|
// XXX: TODO: change this to a `Result<T, NixError>`
|
||||||
type NixResult<T> = Result<T, NixErrorCode>;
|
type NixResult<T> = Result<T, NixErrorCode>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct NixError {
|
pub struct NixError {
|
||||||
pub code: NixErrorCode,
|
pub err: NixErrorCode,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub msg: Option<String>,
|
pub msg: String,
|
||||||
pub info_msg: Option<String>,
|
pub info_msg: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This object stores error state.
|
/// This object stores error state.
|
||||||
|
|
@ -101,26 +125,37 @@ impl ErrorContext {
|
||||||
/// Check the error code and return an error if it's not `NIX_OK`.
|
/// Check the error code and return an error if it's not `NIX_OK`.
|
||||||
///
|
///
|
||||||
/// We recommend to use `check_call!` if possible.
|
/// We recommend to use `check_call!` if possible.
|
||||||
pub fn peak(&self) -> Result<(), NixErrorCode> {
|
pub fn peak(&self) -> Option<NixError> {
|
||||||
// NixError::from( unsafe { sys::nix_err_code(self.as_ptr())}, "");
|
// NixError::from( unsafe { sys::nix_err_code(self.as_ptr())}, "");
|
||||||
|
|
||||||
let err = unsafe { sys::nix_err_code(self.inner.as_ptr()) };
|
// let err = unsafe { sys::nix_err_code(self.inner.as_ptr()) };
|
||||||
if err != sys::nix_err_NIX_OK {
|
// if err != sys::nix_err_NIX_OK {
|
||||||
// msgp is a borrowed pointer (pointing into the context), so we don't need to free it
|
// // msgp is a borrowed pointer (pointing into the context), so we don't need to free it
|
||||||
let msgp = unsafe { sys::nix_err_msg(null_mut(), self.inner.as_ptr(), null_mut()) };
|
// let msgp = unsafe { sys::nix_err_msg(null_mut(), self.inner.as_ptr(), null_mut()) };
|
||||||
// Turn the i8 pointer into a Rust string by copying
|
// // Turn the i8 pointer into a Rust string by copying
|
||||||
let msg: &str = unsafe { core::ffi::CStr::from_ptr(msgp).to_str()? };
|
// let msg: &str = unsafe { core::ffi::CStr::from_ptr(msgp).to_str()? };
|
||||||
bail!("{}", msg);
|
// bail!("{}", msg);
|
||||||
|
// }
|
||||||
|
// Ok(())
|
||||||
|
|
||||||
|
let result = self.get_code();
|
||||||
|
match result {
|
||||||
|
Ok(()) => None,
|
||||||
|
Err(err) => Some(NixError {
|
||||||
|
err,
|
||||||
|
name: self.get_name()?,
|
||||||
|
msg: self.get_msg()?,
|
||||||
|
info_msg: self.get_info_msg()?,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self) -> Result<(), NixErrorCode> {
|
pub fn pop(&mut self) -> Option<NixError> {
|
||||||
let result = self.peak();
|
let error = self.peak();
|
||||||
if result.is_err() {
|
if error.is_some() {
|
||||||
self.clear();
|
self.clear();
|
||||||
}
|
}
|
||||||
result
|
error
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
|
|
@ -137,19 +172,19 @@ impl ErrorContext {
|
||||||
NixErrorCode::from(unsafe { sys::nix_err_code(self.as_ptr()) }, "nix_err_code")
|
NixErrorCode::from(unsafe { sys::nix_err_code(self.as_ptr()) }, "nix_err_code")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_name(&self, result: NixResult<()>) -> Option<String> {
|
/// Returns None if no [self.code] is [sys::nix_err_NIX_OK].
|
||||||
match result {
|
pub(crate) fn get_name(&self) -> Option<String> {
|
||||||
Err(_) => unsafe {
|
unsafe {
|
||||||
let ctx = null_mut();
|
let ctx = null_mut();
|
||||||
wrap_libnix_string_callback("nix_err_name", |callback, user_data| {
|
// NOTE: an Err here only occurs when "Last error was not a nix error"
|
||||||
sys::nix_err_name(ctx, self.as_ptr(), Some(callback), user_data)
|
wrap_libnix_string_callback("nix_err_name", |callback, user_data| {
|
||||||
})
|
sys::nix_err_name(ctx, self.as_ptr(), Some(callback), user_data)
|
||||||
.ok()
|
})
|
||||||
},
|
.ok()
|
||||||
Ok(_) => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns None if no [self.code] is [sys::nix_err_NIX_OK].
|
||||||
/// # Note
|
/// # Note
|
||||||
/// On failure [sys::nix_err_name] does the following if the error
|
/// On failure [sys::nix_err_name] does the following if the error
|
||||||
/// has the error code [sys::nix_err_NIX_OK]:
|
/// has the error code [sys::nix_err_NIX_OK]:
|
||||||
|
|
@ -159,26 +194,33 @@ impl ErrorContext {
|
||||||
/// ```
|
/// ```
|
||||||
/// Hence we can just test whether the returned pointer is a `NULL` pointer,
|
/// Hence we can just test whether the returned pointer is a `NULL` pointer,
|
||||||
/// and avoid passing in a [sys::nix_c_context] struct.
|
/// and avoid passing in a [sys::nix_c_context] struct.
|
||||||
pub(crate) fn get_msg(&self, result: NixResult<()>) -> Option<String> {
|
pub(crate) fn get_msg(&self) -> Option<String> {
|
||||||
match result {
|
unsafe {
|
||||||
Err(_) => unsafe {
|
let ctx = null_mut();
|
||||||
let ctx = null_mut();
|
let msg_ptr: *const c_char = sys::nix_err_msg(ctx, self.as_ptr(), null_mut());
|
||||||
let msg_ptr: *const c_char = sys::nix_err_msg(ctx, self.as_ptr(), null_mut());
|
|
||||||
|
|
||||||
if msg_ptr.is_null() {
|
if msg_ptr.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
match CStr::from_ptr(msg_ptr).to_str() {
|
match CStr::from_ptr(msg_ptr).to_str() {
|
||||||
Ok(msg_str) => Some(msg_str.to_string()),
|
Ok(msg_str) => Some(msg_str.to_string()),
|
||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
}
|
}
|
||||||
},
|
|
||||||
Ok(_) => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_info_msg(&self) -> Option<String> {}
|
/// Returns None if no [self.code] is [sys::nix_err_NIX_OK].
|
||||||
|
pub(crate) fn get_info_msg(&self) -> Option<String> {
|
||||||
|
unsafe {
|
||||||
|
let ctx = null_mut();
|
||||||
|
// NOTE: an Err here only occurs when "Last error was not a nix error"
|
||||||
|
wrap_libnix_string_callback("nix_err_name", |callback, user_data| {
|
||||||
|
sys::nix_err_info_msg(ctx, self.as_ptr(), Some(callback), user_data)
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_one_call_or_key_none<T, F>(&mut self, f: F) -> Result<Option<T>, NixErrorCode>
|
pub fn check_one_call_or_key_none<T, F>(&mut self, f: F) -> Result<Option<T>, NixErrorCode>
|
||||||
where
|
where
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use crate::sys;
|
||||||
|
|
||||||
/// Standard (nix_err) and some additional error codes
|
/// Standard (nix_err) and some additional error codes
|
||||||
/// produced by the libnix C API.
|
/// produced by the libnix C API.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum NixErrorCode {
|
pub enum NixErrorCode {
|
||||||
/// A generic Nix error occurred.
|
/// A generic Nix error occurred.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue