ok nvm *mut was im stupid
This commit is contained in:
parent
648aadf5ab
commit
ff28c6f13f
5 changed files with 103 additions and 80 deletions
|
|
@ -22,6 +22,7 @@
|
||||||
// };
|
// };
|
||||||
|
|
||||||
use std::ffi::c_uint;
|
use std::ffi::c_uint;
|
||||||
|
use std::ffi::c_void;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use super::{NixError, NixideResult};
|
use super::{NixError, NixideResult};
|
||||||
|
|
@ -269,10 +270,16 @@ impl ErrorContext {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub(super) fn get_nix_err_name(&self) -> Option<String> {
|
pub(super) fn get_nix_err_name(&self) -> Option<String> {
|
||||||
|
#[allow(unused_unsafe)] // XXX: TODO: remove this `unused_unsafe`
|
||||||
unsafe {
|
unsafe {
|
||||||
// NOTE: an Err here only occurs when "Last error was not a nix error"
|
// NOTE: an Err here only occurs when "Last error was not a nix error"
|
||||||
wrap::nix_string_callback!(|callback, userdata: &mut __UserData, ctx: &ErrorContext| {
|
wrap::nix_string_callback!(|callback, userdata: *mut __UserData, ctx: &ErrorContext| {
|
||||||
sys::nix_err_name(ctx.as_ptr(), self.as_ptr(), Some(callback), userdata)
|
sys::nix_err_name(
|
||||||
|
ctx.as_ptr(),
|
||||||
|
self.as_ptr(),
|
||||||
|
Some(callback),
|
||||||
|
userdata as *mut c_void,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
@ -314,10 +321,16 @@ impl ErrorContext {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub(super) fn get_nix_err_info_msg(&self) -> Option<String> {
|
pub(super) fn get_nix_err_info_msg(&self) -> Option<String> {
|
||||||
|
#[allow(unused_unsafe)] // XXX: TODO: remove this `unused_unsafe`
|
||||||
unsafe {
|
unsafe {
|
||||||
// NOTE: an Err here only occurs when "Last error was not a nix error"
|
// NOTE: an Err here only occurs when "Last error was not a nix error"
|
||||||
wrap::nix_string_callback!(|callback, user_data, ctx: &ErrorContext| {
|
wrap::nix_string_callback!(|callback, userdata, ctx: &ErrorContext| {
|
||||||
sys::nix_err_info_msg(ctx.as_ptr(), self.as_ptr(), Some(callback), user_data)
|
sys::nix_err_info_msg(
|
||||||
|
ctx.as_ptr(),
|
||||||
|
self.as_ptr(),
|
||||||
|
Some(callback),
|
||||||
|
userdata as *mut c_void,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,31 +34,3 @@ impl CCharPtrExt for *const c_char {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: TODO: remove if unused
|
|
||||||
// pub trait CCharPtrExt {
|
|
||||||
// fn to_utf8_string(self) -> Result<String, Option<Utf8Error>>;
|
|
||||||
//
|
|
||||||
// fn to_utf8_string_n(self, n: usize) -> Result<String, Option<Utf8Error>>;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// impl CCharPtrExt for *const c_char {
|
|
||||||
// fn to_utf8_string(self) -> Result<String, Option<Utf8Error>> {
|
|
||||||
// if self.is_null() {
|
|
||||||
// return Err(None);
|
|
||||||
// }
|
|
||||||
// let cstr = unsafe { CStr::from_ptr(self) };
|
|
||||||
// match cstr.to_str() {
|
|
||||||
// Ok(s) => Ok(s.to_owned()),
|
|
||||||
// Err(err) => Err(Some(err)),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn to_utf8_string_n(self, n: usize) -> Result<String, Option<Utf8Error>> {
|
|
||||||
// if self.is_null() || n == 0 {
|
|
||||||
// return Err(None);
|
|
||||||
// }
|
|
||||||
// let bytes = unsafe { from_raw_parts(self.cast::<u8>(), n as usize) };
|
|
||||||
// from_utf8(bytes).map(str::to_string).map_err(Some)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ impl Store {
|
||||||
})?;
|
})?;
|
||||||
let store_path = StorePath { inner };
|
let store_path = StorePath { inner };
|
||||||
|
|
||||||
let callback = userdata.inner;
|
let callback = unsafe { (*userdata).inner };
|
||||||
callback(output_name.as_ref(), &store_path);
|
callback(output_name.as_ref(), &store_path);
|
||||||
|
|
||||||
Ok((output_name, store_path))
|
Ok((output_name, store_path))
|
||||||
|
|
@ -213,27 +213,43 @@ impl Store {
|
||||||
///
|
///
|
||||||
/// If the store doesn't have a version (like the dummy store), returns None
|
/// If the store doesn't have a version (like the dummy store), returns None
|
||||||
pub fn version(&self) -> Result<String, NixideError> {
|
pub fn version(&self) -> Result<String, NixideError> {
|
||||||
wrap::nix_string_callback(|callback, user_data, ctx| unsafe {
|
wrap::nix_string_callback!(
|
||||||
sys::nix_store_get_version(ctx.as_ptr(), self.inner.as_ptr(), Some(callback), user_data)
|
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||||
})
|
sys::nix_store_get_version(
|
||||||
|
ctx.as_ptr(),
|
||||||
|
self.inner.as_ptr(),
|
||||||
|
Some(callback),
|
||||||
|
userdata as *mut c_void,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the URI of a Nix store
|
/// Get the URI of a Nix store
|
||||||
pub fn uri(&self) -> Result<String, NixideError> {
|
pub fn uri(&self) -> Result<String, NixideError> {
|
||||||
wrap::nix_string_callback(|callback, user_data, ctx| unsafe {
|
wrap::nix_string_callback!(
|
||||||
sys::nix_store_get_uri(ctx.as_ptr(), self.inner.as_ptr(), Some(callback), user_data)
|
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||||
})
|
sys::nix_store_get_uri(
|
||||||
|
ctx.as_ptr(),
|
||||||
|
self.inner.as_ptr(),
|
||||||
|
Some(callback),
|
||||||
|
userdata as *mut c_void,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn store_dir(&self) -> Result<PathBuf, NixideError> {
|
pub fn store_dir(&self) -> Result<PathBuf, NixideError> {
|
||||||
wrap::nix_pathbuf_callback(|callback, user_data, ctx| unsafe {
|
wrap::nix_pathbuf_callback!(
|
||||||
sys::nix_store_get_storedir(
|
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||||
ctx.as_ptr(),
|
sys::nix_store_get_storedir(
|
||||||
self.inner.as_ptr(),
|
ctx.as_ptr(),
|
||||||
Some(callback),
|
self.inner.as_ptr(),
|
||||||
user_data,
|
Some(callback),
|
||||||
)
|
userdata as *mut c_void,
|
||||||
})
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_closure_to(
|
pub fn copy_closure_to(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::ffi::CString;
|
use std::ffi::{c_void, CString};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
|
@ -56,8 +56,8 @@ impl StorePath {
|
||||||
/// Returns an error if the name cannot be retrieved.
|
/// Returns an error if the name cannot be retrieved.
|
||||||
///
|
///
|
||||||
pub fn name(&self) -> Result<String, NixideError> {
|
pub fn name(&self) -> Result<String, NixideError> {
|
||||||
wrap::nix_string_callback(|callback, user_data, _| unsafe {
|
wrap::nix_string_callback!(|callback, userdata: *mut __UserData, _| unsafe {
|
||||||
sys::nix_store_path_name(self.inner.as_ptr(), Some(callback), user_data);
|
sys::nix_store_path_name(self.inner.as_ptr(), Some(callback), userdata as *mut c_void);
|
||||||
// NOTE: nix_store_path_name doesn't return nix_err, so we force it to return successfully
|
// NOTE: nix_store_path_name doesn't return nix_err, so we force it to return successfully
|
||||||
nix_err_NIX_OK
|
nix_err_NIX_OK
|
||||||
})
|
})
|
||||||
|
|
@ -85,15 +85,17 @@ impl StorePath {
|
||||||
/// * `store` - The store containing the path
|
/// * `store` - The store containing the path
|
||||||
///
|
///
|
||||||
pub fn real_path(&self, store: &Store) -> Result<PathBuf, NixideError> {
|
pub fn real_path(&self, store: &Store) -> Result<PathBuf, NixideError> {
|
||||||
wrap::nix_pathbuf_callback(|callback, user_data, ctx| unsafe {
|
wrap::nix_pathbuf_callback!(
|
||||||
sys::nix_store_real_path(
|
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||||
ctx.as_ptr(),
|
sys::nix_store_real_path(
|
||||||
store.inner.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.as_ptr(),
|
store.inner.as_ptr(),
|
||||||
Some(callback),
|
self.as_ptr(),
|
||||||
user_data,
|
Some(callback),
|
||||||
)
|
userdata as *mut c_void,
|
||||||
})
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a [StorePath] is valid (i.e. that its corresponding store object
|
/// Check if a [StorePath] is valid (i.e. that its corresponding store object
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,22 @@ impl<S, T> AsMut<UserData<S, T>> for UserData<S, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub(crate) trait VoidPtrIsomorphism {
|
||||||
|
// fn as_void_ptr(self) -> *mut c_void;
|
||||||
|
|
||||||
|
// fn from_void_ptr(ptr: *mut c_void) -> Self;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl<S, T> VoidPtrIsomorphism for *mut UserData<S, T> {
|
||||||
|
// fn as_void_ptr(self) -> *mut c_void {
|
||||||
|
// self as *mut c_void
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn from_void_ptr(ptr: *mut c_void) -> Self {
|
||||||
|
// ptr as Self
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl<S, T> UserData<S, T> {
|
impl<S, T> UserData<S, T> {
|
||||||
/// # Warning
|
/// # Warning
|
||||||
///
|
///
|
||||||
|
|
@ -46,6 +62,8 @@ macro_rules! nonnull {
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
use std::ffi::c_void;
|
||||||
|
|
||||||
pub(crate) use nonnull;
|
pub(crate) use nonnull;
|
||||||
|
|
||||||
macro_rules! nix_fn {
|
macro_rules! nix_fn {
|
||||||
|
|
@ -80,6 +98,7 @@ macro_rules! __nix_callback {
|
||||||
__return
|
__return
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
#[allow(unused_imports)] // XXX: TODO: replace the tail of `nix_callback!` with this macro
|
||||||
pub(crate) use __nix_callback;
|
pub(crate) use __nix_callback;
|
||||||
|
|
||||||
/// `libnix` functions consistently either expect the `userdata`/`user_data` (inconsistently named in the API...)
|
/// `libnix` functions consistently either expect the `userdata`/`user_data` (inconsistently named in the API...)
|
||||||
|
|
@ -95,36 +114,37 @@ macro_rules! nix_callback {
|
||||||
( | $( $($pre:ident : $pre_ty:ty),+ $(,)? )? ; $userdata:ident : $userdata_type:ty ; $( $($post:ident : $post_ty:ty),+ $(,)? )? | -> $ret:ty $body:block, $function:expr $(,)? ) => {{
|
( | $( $($pre:ident : $pre_ty:ty),+ $(,)? )? ; $userdata:ident : $userdata_type:ty ; $( $($post:ident : $post_ty:ty),+ $(,)? )? | -> $ret:ty $body:block, $function:expr $(,)? ) => {{
|
||||||
type __UserData = $crate::util::wrap::UserData<$userdata_type, $ret>;
|
type __UserData = $crate::util::wrap::UserData<$userdata_type, $ret>;
|
||||||
// create a function item that wraps the closure body (so it has a concrete type)
|
// create a function item that wraps the closure body (so it has a concrete type)
|
||||||
|
#[allow(unused_variables)]
|
||||||
unsafe extern "C" fn __captured_fn(
|
unsafe extern "C" fn __captured_fn(
|
||||||
$($( $pre: $pre_ty, )*)?
|
$($( $pre: $pre_ty, )*)?
|
||||||
$userdata: &mut __UserData,
|
$userdata: *mut __UserData,
|
||||||
$($( $post: $post_ty, )*)?
|
$($( $post: $post_ty, )*)?
|
||||||
) -> $ret $body
|
) -> $ret { $body }
|
||||||
|
|
||||||
unsafe extern "C" fn __wrapper_callback(
|
unsafe extern "C" fn __wrapper_callback(
|
||||||
$($( $pre: $pre_ty, )*)?
|
$($( $pre: $pre_ty, )*)?
|
||||||
$userdata: &mut __UserData,
|
$userdata: *mut ::std::ffi::c_void,
|
||||||
$($( $post: $post_ty, )*)?
|
$($( $post: $post_ty, )*)?
|
||||||
) {
|
) {
|
||||||
let stored_retval = &raw mut $userdata.retval;
|
|
||||||
|
|
||||||
let retval = unsafe {
|
|
||||||
__captured_fn(
|
|
||||||
$($( $pre, )*)?
|
|
||||||
$userdata,
|
|
||||||
$($( $post, )*)?
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let userdata_ = $userdata as *mut __UserData;
|
||||||
|
let stored_retval = &raw mut (*userdata_).retval;
|
||||||
|
|
||||||
|
let retval =
|
||||||
|
__captured_fn(
|
||||||
|
$($( $pre, )*)?
|
||||||
|
userdata_,
|
||||||
|
$($( $post, )*)?
|
||||||
|
);
|
||||||
|
|
||||||
stored_retval.write(retval)
|
stored_retval.write(retval)
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut __ctx: $crate::errors::ErrorContext = $crate::errors::ErrorContext::new();
|
let mut __ctx: $crate::errors::ErrorContext = $crate::errors::ErrorContext::new();
|
||||||
let mut __state: ::std::mem::MaybeUninit<__UserData> = ::std::mem::MaybeUninit::uninit();
|
let mut __state: ::std::mem::MaybeUninit<__UserData> = ::std::mem::MaybeUninit::zeroed();
|
||||||
|
|
||||||
$function(__wrapper_callback, &mut __state, &__ctx);
|
$function(__wrapper_callback, __state.as_mut_ptr(), &__ctx);
|
||||||
|
|
||||||
__ctx.pop().and_then(|_| unsafe { __state.assume_init().retval })
|
__ctx.pop().and_then(|_| unsafe { __state.assume_init().retval })
|
||||||
}};
|
}};
|
||||||
|
|
@ -133,20 +153,20 @@ pub(crate) use nix_callback;
|
||||||
|
|
||||||
// XXX: TODO: convert these to declarative macros
|
// XXX: TODO: convert these to declarative macros
|
||||||
macro_rules! nix_string_callback {
|
macro_rules! nix_string_callback {
|
||||||
($callback:expr $(,)?) => {{
|
($function:expr $(,)?) => {{
|
||||||
$crate::util::wrap::nix_callback!(
|
$crate::util::wrap::nix_callback!(
|
||||||
|start: *const ::std::ffi::c_char, n: ::std::ffi::c_uint; userdata: ();| -> $crate::NixideResult<String> {
|
|start: *const ::std::ffi::c_char, n: ::std::ffi::c_uint; userdata: ();| -> $crate::NixideResult<String> {
|
||||||
start.to_utf8_string_n(n as usize)
|
$crate::stdext::CCharPtrExt::to_utf8_string_n(start, n as usize)
|
||||||
},
|
},
|
||||||
$callback
|
$function
|
||||||
)
|
)
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
pub(crate) use nix_string_callback;
|
pub(crate) use nix_string_callback;
|
||||||
|
|
||||||
macro_rules! nix_pathbuf_callback {
|
macro_rules! nix_pathbuf_callback {
|
||||||
($callback:expr $(,)?) => {{
|
($function:expr $(,)?) => {{
|
||||||
$crate::util::wrap::nix_string_callback!($callback).map(::std::path::PathBuf::from)
|
$crate::util::wrap::nix_string_callback!($function).map(::std::path::PathBuf::from)
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
pub(crate) use nix_pathbuf_callback;
|
pub(crate) use nix_pathbuf_callback;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue