nix_callback! macro now works <3
This commit is contained in:
parent
ab9886281a
commit
bfb2010f19
9 changed files with 88 additions and 163 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -190,6 +190,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
name = "nixide"
|
name = "nixide"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"libc",
|
||||||
"nixide-sys",
|
"nixide-sys",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"stdext",
|
"stdext",
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,9 @@ util = []
|
||||||
gc = []
|
gc = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nixide-sys = { path = "../nixide-sys", version = "0.1.0" }
|
libc = "0.2.183"
|
||||||
stdext = "0.3.3"
|
stdext = "0.3.3"
|
||||||
|
nixide-sys = { path = "../nixide-sys", version = "0.1.0" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = "3.4.0"
|
serial_test = "3.4.0"
|
||||||
|
|
|
||||||
|
|
@ -137,15 +137,15 @@ impl Display for NixideError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AsErr<T> {
|
// pub trait AsErr<T> {
|
||||||
fn as_err(self) -> Result<(), T>;
|
// fn as_err(self) -> Result<(), T>;
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl AsErr<NixideError> for Option<NixideError> {
|
// impl AsErr<NixideError> for Option<NixideError> {
|
||||||
fn as_err(self) -> Result<(), NixideError> {
|
// fn as_err(self) -> Result<(), NixideError> {
|
||||||
match self {
|
// match self {
|
||||||
Some(err) => Err(err),
|
// Some(err) => Err(err),
|
||||||
None => Ok(()),
|
// None => Ok(()),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
// #![warn(missing_docs)]
|
// #![warn(missing_docs)]
|
||||||
|
|
||||||
|
// #[allow(unused_extern_crates)]
|
||||||
|
pub extern crate libc;
|
||||||
|
pub extern crate nixide_sys as sys;
|
||||||
|
|
||||||
pub(crate) mod errors;
|
pub(crate) mod errors;
|
||||||
// mod expr;
|
// mod expr;
|
||||||
// mod flake;
|
// mod flake;
|
||||||
|
|
@ -15,8 +19,6 @@ pub use store::{Store, StorePath};
|
||||||
pub use verbosity::NixVerbosity;
|
pub use verbosity::NixVerbosity;
|
||||||
pub use version::NixVersion;
|
pub use version::NixVersion;
|
||||||
|
|
||||||
pub use nixide_sys as sys;
|
|
||||||
|
|
||||||
/// Sets the verbosity level
|
/// Sets the verbosity level
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ use std::result::Result;
|
||||||
|
|
||||||
use crate::errors::{new_nixide_error, ErrorContext};
|
use crate::errors::{new_nixide_error, ErrorContext};
|
||||||
use crate::stdext::CCharPtrExt;
|
use crate::stdext::CCharPtrExt;
|
||||||
use crate::util::wrap::{self, UserData};
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr;
|
use crate::util::wrappers::AsInnerPtr;
|
||||||
use crate::{NixideError, NixideResult};
|
use crate::{NixideError, NixideResult};
|
||||||
use nixide_sys as sys;
|
use nixide_sys as sys;
|
||||||
|
|
@ -87,96 +87,42 @@ impl Store {
|
||||||
pub fn realise<F>(
|
pub fn realise<F>(
|
||||||
&self,
|
&self,
|
||||||
path: &StorePath,
|
path: &StorePath,
|
||||||
callback: fn(&str, &StorePath),
|
user_callback: fn(&str, &StorePath),
|
||||||
) -> NixideResult<(String, StorePath)> {
|
) -> NixideResult<Vec<(String, StorePath)>> {
|
||||||
// // Type alias for our userdata: (outputs vector, context)
|
|
||||||
// type Userdata = (
|
|
||||||
// Vec<(String, StorePath)>,
|
|
||||||
// Arc<ErrorContext>,
|
|
||||||
// fn(&str, &StorePath),
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// // Callback function that will be called for each realized output
|
|
||||||
// unsafe extern "C" fn realise_callback(
|
|
||||||
// userdata: *mut c_void,
|
|
||||||
// out_name_ptr: *const c_char,
|
|
||||||
// out_path_ptr: *const sys::StorePath,
|
|
||||||
// ) {
|
|
||||||
// // SAFETY: userdata is a valid pointer to our (Vec, Arc<Context>) tuple
|
|
||||||
// let (outputs, ctx, callback) = unsafe { &mut *(userdata as *mut Userdata) };
|
|
||||||
//
|
|
||||||
// // SAFETY: outname is a valid C string from Nix
|
|
||||||
// let output_name = if !out_name_ptr.is_null() {
|
|
||||||
// unsafe { CStr::from_ptr(out_name_ptr).to_string_lossy().into_owned() }
|
|
||||||
// } else {
|
|
||||||
// String::from("out") // Default output name
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// // SAFETY: out is a valid StorePath pointer from Nix, we need to clone it
|
|
||||||
// // because Nix owns the original and may free it after the callback
|
|
||||||
// if !out_path_ptr.is_null() {
|
|
||||||
// let cloned_path_ptr =
|
|
||||||
// unsafe { sys::nix_store_path_clone(out_path_ptr as *mut sys::StorePath) };
|
|
||||||
// if let Some(inner) = NonNull::new(cloned_path_ptr) {
|
|
||||||
// let store_path = StorePath { inner };
|
|
||||||
//
|
|
||||||
// callback(output_name.as_ref(), &store_path);
|
|
||||||
//
|
|
||||||
// outputs.push((output_name, store_path));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Create userdata with empty outputs vector and context
|
|
||||||
// let mut userdata: Userdata = (Vec::new(), Arc::new(ErrorContext::new()), callback);
|
|
||||||
// let userdata_ptr = &mut userdata as *mut Userdata as *mut std::os::raw::c_void;
|
|
||||||
//
|
|
||||||
// // SAFETY: All pointers are valid, callback is compatible with the FFI signature
|
|
||||||
// // - self._context is valid for the duration of this call
|
|
||||||
// // - self.inner is valid (checked in Store::open)
|
|
||||||
// // - path.inner is valid (checked in StorePath::parse)
|
|
||||||
// // - userdata_ptr points to valid stack memory
|
|
||||||
// // - realize_callback matches the expected C function signature
|
|
||||||
// let err = unsafe {
|
|
||||||
// sys::nix_store_realise(
|
|
||||||
// ctx.as_ptr(),
|
|
||||||
// self.inner.as_ptr(),
|
|
||||||
// path.as_ptr(),
|
|
||||||
// userdata_ptr,
|
|
||||||
// Some(realise_callback),
|
|
||||||
// )
|
|
||||||
// };
|
|
||||||
|
|
||||||
wrap::nix_callback!(
|
wrap::nix_callback!(
|
||||||
|; userdata: fn(&str, &StorePath);
|
|; userdata: fn(&str, &StorePath);
|
||||||
output_name_ptr: *const c_char,
|
output_name_ptr: *const c_char,
|
||||||
output_path_ptr: *const sys::StorePath|
|
output_path_ptr: *const sys::StorePath|
|
||||||
-> NixideResult<(String, StorePath)> {
|
-> Vec<(String, StorePath)> {
|
||||||
// XXX: TODO: test to see if this is ever null ("out" as a default feels unsafe...)
|
// XXX: TODO: test to see if this is ever null ("out" as a default feels unsafe...)
|
||||||
// let output_name = output_name_ptr.to_utf8_string().unwrap_or("out".to_owned());
|
|
||||||
// NOTE: this also ensures `output_name_ptr` isn't null
|
// NOTE: this also ensures `output_name_ptr` isn't null
|
||||||
let output_name = output_name_ptr.to_utf8_string()?;
|
let output_name = output_name_ptr.to_utf8_string().expect("IDK1");
|
||||||
|
|
||||||
let inner = wrap::nix_ptr_fn!(|ctx| unsafe {
|
let inner = wrap::nix_ptr_fn!(|ctx| unsafe {
|
||||||
sys::nix_store_path_clone(output_path_ptr as *mut sys::StorePath)
|
sys::nix_store_path_clone(output_path_ptr as *mut sys::StorePath)
|
||||||
})?;
|
}).expect("IDK2");
|
||||||
let store_path = StorePath { inner };
|
let store_path = StorePath { inner };
|
||||||
|
|
||||||
let callback = unsafe { (*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))
|
(output_name, store_path);
|
||||||
},
|
},
|
||||||
|callback,
|
|callback,
|
||||||
state: *mut UserData<fn(&str, &StorePath), NixideResult<(String, StorePath)>>,
|
state: *mut __UserData,
|
||||||
ctx: &ErrorContext| unsafe {
|
ctx: &ErrorContext| unsafe {
|
||||||
|
// register userdata
|
||||||
|
// WARNING: Using `write` instead of assignment via `=`
|
||||||
|
// WARNING: to not call `drop` on the old, uninitialized value.
|
||||||
|
(&raw mut (*state).inner).write(user_callback);
|
||||||
|
|
||||||
sys::nix_store_realise(
|
sys::nix_store_realise(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.inner.as_ptr(),
|
self.inner.as_ptr(),
|
||||||
path.as_ptr(),
|
path.as_ptr(),
|
||||||
(*state).inner_ptr() as *mut c_void,
|
(*state).inner_ptr() as *mut c_void,
|
||||||
Some(callback),
|
Some(callback),
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,6 @@ fn test_store_opening() {
|
||||||
sys::nix_libstore_init(ctx.as_ptr());
|
sys::nix_libstore_init(ctx.as_ptr());
|
||||||
ctx.pop()
|
ctx.pop()
|
||||||
.expect("nix_libstore_init failed with bad ErrorContext");
|
.expect("nix_libstore_init failed with bad ErrorContext");
|
||||||
sys::nix_libexpr_init(ctx.as_ptr());
|
|
||||||
ctx.pop()
|
|
||||||
.expect("nix_libexpr_init failed with bad ErrorContext");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let _store = Store::open(None).expect("Failed to open store");
|
let _store = Store::open(None).expect("Failed to open store");
|
||||||
|
|
@ -35,9 +32,6 @@ fn test_store_path_parse() {
|
||||||
sys::nix_libstore_init(ctx.as_ptr());
|
sys::nix_libstore_init(ctx.as_ptr());
|
||||||
ctx.pop()
|
ctx.pop()
|
||||||
.expect("nix_libstore_init failed with bad ErrorContext");
|
.expect("nix_libstore_init failed with bad ErrorContext");
|
||||||
sys::nix_libexpr_init(ctx.as_ptr());
|
|
||||||
ctx.pop()
|
|
||||||
.expect("nix_libexpr_init failed with bad ErrorContext");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let store = Store::open(None).expect("Failed to open store");
|
let store = Store::open(None).expect("Failed to open store");
|
||||||
|
|
@ -58,9 +52,6 @@ fn test_store_path_clone() {
|
||||||
sys::nix_libstore_init(ctx.as_ptr());
|
sys::nix_libstore_init(ctx.as_ptr());
|
||||||
ctx.pop()
|
ctx.pop()
|
||||||
.expect("nix_libstore_init failed with bad ErrorContext");
|
.expect("nix_libstore_init failed with bad ErrorContext");
|
||||||
sys::nix_libexpr_init(ctx.as_ptr());
|
|
||||||
ctx.pop()
|
|
||||||
.expect("nix_libexpr_init failed with bad ErrorContext");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let store = Store::open(None).expect("Failed to open store");
|
let store = Store::open(None).expect("Failed to open store");
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ macro_rules! panic_issue {
|
||||||
|
|
||||||
macro_rules! panic_issue_call_failed {
|
macro_rules! panic_issue_call_failed {
|
||||||
() => {{
|
() => {{
|
||||||
crate::util::panic_issue!("[nixide] call to `{}` failed", stdext::debug_name!())
|
crate::util::panic_issue!("[nixide] call to `{}` failed", $crate::stdext::debug_name!())
|
||||||
}};
|
}};
|
||||||
($($arg:expr),*) => {{
|
($($arg:expr),*) => {{
|
||||||
crate::util::panic_issue!("[nixide] call to `{}` failed with \"{}\"", stdext::debug_name!(), format!($($arg),*))
|
crate::util::panic_issue!("[nixide] call to `{}` failed with \"{}\"", $crate::stdext::debug_name!(), format!($($arg),*))
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ pub(crate) struct UserData<S, T> {
|
||||||
pub inner: S,
|
pub inner: S,
|
||||||
pub retval: T,
|
pub retval: T,
|
||||||
|
|
||||||
|
// XXX: TODO: write impl functions to set and get these values,
|
||||||
|
// XXX: TODO: and another one to unwrap a `MaybeUninit<UserData<S, T>>`
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
pub init_inner: bool,
|
pub init_inner: bool,
|
||||||
|
|
||||||
|
|
@ -18,14 +20,6 @@ impl<S, T> AsMut<UserData<S, T>> for UserData<S, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, T> UserData<S, T> {
|
impl<S, T> UserData<S, T> {
|
||||||
/// # Warning
|
|
||||||
///
|
|
||||||
/// Ensure `self.retval` has been initialised before unwrapping!
|
|
||||||
///
|
|
||||||
// pub unsafe fn unwrap(self) -> (S, T) {
|
|
||||||
// (self.inner, self.retval)
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut Self {
|
pub unsafe fn as_mut_ptr(&mut self) -> *mut Self {
|
||||||
self as *mut Self
|
self as *mut Self
|
||||||
}
|
}
|
||||||
|
|
@ -36,10 +30,6 @@ impl<S, T> UserData<S, T> {
|
||||||
&raw mut (*ptr).inner
|
&raw mut (*ptr).inner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub unsafe fn retval_ptr(&mut self) -> *mut c_void {
|
|
||||||
// &mut self.retval as *mut T as *mut c_void
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! nonnull {
|
macro_rules! nonnull {
|
||||||
|
|
@ -73,42 +63,27 @@ macro_rules! nix_ptr_fn {
|
||||||
}
|
}
|
||||||
pub(crate) use nix_ptr_fn;
|
pub(crate) use nix_ptr_fn;
|
||||||
|
|
||||||
macro_rules! __nix_callback {
|
|
||||||
($userdata_type:ty, $ret:ty, $callback:expr) => {{
|
|
||||||
let mut __ctx = $crate::errors::ErrorContext::new();
|
|
||||||
let mut __state: ::std::mem::MaybeUninit<__UserData> = ::std::mem::MaybeUninit::uninit();
|
|
||||||
|
|
||||||
$callback(__wrapper_callback, __state.as_mut_ptr(), &__ctx);
|
|
||||||
|
|
||||||
// add type annotations for compiler
|
|
||||||
let __return: $ret = __ctx
|
|
||||||
.pop()
|
|
||||||
.and_then(|_| unsafe { __state.assume_init().retval });
|
|
||||||
__return
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
#[allow(unused_imports)] // XXX: TODO: replace the tail of `nix_callback!` with this macro
|
|
||||||
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...)
|
||||||
/// field to be the first or last parameter (differs between function). The `nix_callback!` macro allows the
|
/// field to be the first or last parameter (differs between function). The `nix_callback!` macro allows the
|
||||||
/// position to be specified by either the following syntax:
|
/// position to be specified by either the following syntax:
|
||||||
///
|
///
|
||||||
/// ```rs
|
/// ```rs
|
||||||
/// nix_callback(userdata; ...); // first parameter
|
/// nix_callback!(; userdata; ...); // first parameter
|
||||||
/// nix_callback(...; userdata); // last parameter
|
/// nix_callback!(...; userdata; ); // last parameter
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
macro_rules! nix_callback {
|
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)
|
||||||
|
// WARNING: this function must have no return type, use the `UserData.inner`
|
||||||
|
// WARNING: field instead as an `out` pointer.
|
||||||
#[allow(unused_variables)]
|
#[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 }
|
) { $body }
|
||||||
|
|
||||||
unsafe extern "C" fn __wrapper_callback(
|
unsafe extern "C" fn __wrapper_callback(
|
||||||
$($( $pre: $pre_ty, )*)?
|
$($( $pre: $pre_ty, )*)?
|
||||||
|
|
@ -116,17 +91,12 @@ macro_rules! nix_callback {
|
||||||
$($( $post: $post_ty, )*)?
|
$($( $post: $post_ty, )*)?
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let userdata_ = $userdata as *mut __UserData;
|
__captured_fn(
|
||||||
let stored_retval = &raw mut (*userdata_).retval;
|
$($( $pre, )*)?
|
||||||
|
// userdata_,
|
||||||
let retval =
|
$userdata as *mut __UserData,
|
||||||
__captured_fn(
|
$($( $post, )*)?
|
||||||
$($( $pre, )*)?
|
);
|
||||||
userdata_,
|
|
||||||
$($( $post, )*)?
|
|
||||||
);
|
|
||||||
|
|
||||||
stored_retval.write(retval)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,21 +106,35 @@ macro_rules! nix_callback {
|
||||||
$function(__wrapper_callback, __state.as_mut_ptr(), &__ctx);
|
$function(__wrapper_callback, __state.as_mut_ptr(), &__ctx);
|
||||||
|
|
||||||
// type annotations for compiler
|
// type annotations for compiler
|
||||||
let __result: $ret = __ctx.pop().and_then(|_| unsafe { __state.assume_init().retval });
|
let __return: $crate::NixideResult<$ret> = __ctx.pop().and_then(|_| ::std::result::Result::Ok(unsafe { __state.assume_init().retval }));
|
||||||
__result
|
__return
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
pub(crate) use nix_callback;
|
pub(crate) use nix_callback;
|
||||||
|
|
||||||
// XXX: TODO: convert these to declarative macros
|
|
||||||
macro_rules! nix_string_callback {
|
macro_rules! nix_string_callback {
|
||||||
($function:expr $(,)?) => {{
|
($function:expr $(,)?) => {{
|
||||||
$crate::util::wrap::nix_callback!(
|
#[repr(C)]
|
||||||
|start: *const ::std::ffi::c_char, n: ::std::ffi::c_uint; userdata: ();| -> $crate::NixideResult<String> {
|
struct __ReturnType {
|
||||||
$crate::stdext::CCharPtrExt::to_utf8_string_n(start, n as usize)
|
start: *const ::std::ffi::c_char,
|
||||||
|
n: ::std::ffi::c_uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
let __result = $crate::util::wrap::nix_callback!(
|
||||||
|
|start: *const ::std::ffi::c_char, n: ::std::ffi::c_uint; userdata: ();| -> (*const ::std::ffi::c_char, ::std::ffi::c_uint) {
|
||||||
|
unsafe {
|
||||||
|
let retval = &raw mut (*userdata).retval;
|
||||||
|
retval.write((start, n))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
$function
|
$function
|
||||||
)
|
);
|
||||||
|
|
||||||
|
__result.and_then(|(start, n)| {
|
||||||
|
let __return = $crate::stdext::CCharPtrExt::to_utf8_string_n(start, n as usize);
|
||||||
|
|
||||||
|
__return
|
||||||
|
})
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
pub(crate) use nix_string_callback;
|
pub(crate) use nix_string_callback;
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,23 @@
|
||||||
use crate::NixideError;
|
// use crate::NixideError;
|
||||||
|
//
|
||||||
pub trait AsErr<T> {
|
// pub trait AsErr<T> {
|
||||||
fn as_err(self) -> Result<(), T>;
|
// fn as_err(self) -> Result<(), T>;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
impl AsErr<NixideError> for Option<NixideError> {
|
// impl AsErr<NixideError> for Option<NixideError> {
|
||||||
fn as_err(self) -> Result<(), NixideError> {
|
// fn as_err(self) -> Result<(), NixideError> {
|
||||||
match self {
|
// match self {
|
||||||
Some(err) => Err(err),
|
// Some(err) => Err(err),
|
||||||
None => Ok(()),
|
// None => Ok(()),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// pub trait FromC<T> {
|
||||||
|
// /// Creates a new instance of [Self] from the underlying
|
||||||
|
// /// libnix C type [T].
|
||||||
|
// unsafe fn from_c(value: T) -> Self;
|
||||||
|
// }
|
||||||
|
|
||||||
pub trait AsInnerPtr<T> {
|
pub trait AsInnerPtr<T> {
|
||||||
/// Get a pointer to the underlying (`inner`) `libnix` C struct.
|
/// Get a pointer to the underlying (`inner`) `libnix` C struct.
|
||||||
|
|
@ -23,9 +29,3 @@ pub trait AsInnerPtr<T> {
|
||||||
/// in `unsafe` blocks for clarity.
|
/// in `unsafe` blocks for clarity.
|
||||||
unsafe fn as_ptr(&self) -> *mut T;
|
unsafe fn as_ptr(&self) -> *mut T;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait FromC<T> {
|
|
||||||
/// Creates a new instance of [Self] from the underlying
|
|
||||||
/// libnix C type [T].
|
|
||||||
unsafe fn from_c(value: T) -> Self;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue