oh we're pushing
This commit is contained in:
parent
ff28c6f13f
commit
ab9886281a
4 changed files with 79 additions and 55 deletions
|
|
@ -197,10 +197,9 @@ impl Store {
|
|||
///
|
||||
/// ```no_run
|
||||
/// # use std::sync::Arc;
|
||||
/// # use nixide::{Context, Store};
|
||||
/// # use nixide::Store;
|
||||
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// let ctx = Arc::new(Context::new()?);
|
||||
/// let store = Store::open(&ctx, None)?;
|
||||
/// let store = Store::open(None)?;
|
||||
/// let path = store.store_path("/nix/store/...")?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ use crate::errors::{new_nixide_error, ErrorContext};
|
|||
use crate::util::panic_issue_call_failed;
|
||||
use crate::util::wrap;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
use crate::NixideError;
|
||||
use crate::NixideResult;
|
||||
|
||||
use nixide_sys::{self as sys, nix_err_NIX_OK};
|
||||
use nixide_sys as sys;
|
||||
|
||||
/// A path in the Nix store.
|
||||
///
|
||||
|
|
@ -36,7 +36,7 @@ impl StorePath {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the path cannot be parsed.
|
||||
pub fn parse(store: &Store, path: &str) -> Result<Self, NixideError> {
|
||||
pub fn parse(store: &Store, path: &str) -> NixideResult<Self> {
|
||||
let c_path = CString::new(path).or(Err(new_nixide_error!(StringNulByte)))?;
|
||||
|
||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||
|
|
@ -46,6 +46,10 @@ impl StorePath {
|
|||
Ok(Self { inner })
|
||||
}
|
||||
|
||||
pub fn fake_path(store: &Store) -> NixideResult<Self> {
|
||||
Self::parse(store, "/nix/store/00000000000000000000000000000000-fake")
|
||||
}
|
||||
|
||||
/// Get the name component of the store path.
|
||||
///
|
||||
/// This returns the name part of the store path (everything after the hash).
|
||||
|
|
@ -55,11 +59,12 @@ impl StorePath {
|
|||
///
|
||||
/// Returns an error if the name cannot be retrieved.
|
||||
///
|
||||
pub fn name(&self) -> Result<String, NixideError> {
|
||||
pub fn name(&self) -> NixideResult<String> {
|
||||
wrap::nix_string_callback!(|callback, userdata: *mut __UserData, _| unsafe {
|
||||
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
|
||||
nix_err_NIX_OK
|
||||
// XXX: NOTE: now `nix_string_callback` is a macro this isn't necessary
|
||||
// sys::nix_err_NIX_OK
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +89,7 @@ impl StorePath {
|
|||
///
|
||||
/// * `store` - The store containing the path
|
||||
///
|
||||
pub fn real_path(&self, store: &Store) -> Result<PathBuf, NixideError> {
|
||||
pub fn real_path(&self, store: &Store) -> NixideResult<PathBuf> {
|
||||
wrap::nix_pathbuf_callback!(
|
||||
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||
sys::nix_store_real_path(
|
||||
|
|
|
|||
|
|
@ -1,53 +1,82 @@
|
|||
use serial_test::serial;
|
||||
|
||||
use super::*;
|
||||
use super::{Store, StorePath};
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::sys;
|
||||
use crate::util::wrappers::AsInnerPtr as _;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_store_opening() {
|
||||
let mut ctx = ErrorContext::new();
|
||||
unsafe {
|
||||
sys::nix_libutil_init(ctx.as_ptr());
|
||||
ctx.pop()
|
||||
.expect("nix_libutil_init failed with bad ErrorContext");
|
||||
sys::nix_libstore_init(ctx.as_ptr());
|
||||
ctx.pop()
|
||||
.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");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_store_path_parse() {
|
||||
let mut ctx = ErrorContext::new();
|
||||
unsafe {
|
||||
sys::nix_libutil_init(ctx.as_ptr());
|
||||
ctx.pop()
|
||||
.expect("nix_libutil_init failed with bad ErrorContext");
|
||||
sys::nix_libstore_init(ctx.as_ptr());
|
||||
ctx.pop()
|
||||
.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");
|
||||
|
||||
// Try parsing a well-formed store path
|
||||
// Note: This may fail if the path doesn't exist in the store
|
||||
let result = StorePath::parse(&store, "/nix/store/00000000000000000000000000000000-test");
|
||||
|
||||
// We don't assert success here because the path might not exist
|
||||
// This test mainly checks that the API works correctly
|
||||
match result {
|
||||
Ok(_path) => {
|
||||
// Successfully parsed the path
|
||||
}
|
||||
Err(_) => {
|
||||
// Path doesn't exist or is invalid, which is expected
|
||||
}
|
||||
}
|
||||
let result = StorePath::fake_path(&store);
|
||||
result.expect("idk hopefully this fails");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_store_path_clone() {
|
||||
let mut ctx = ErrorContext::new();
|
||||
unsafe {
|
||||
sys::nix_libutil_init(ctx.as_ptr());
|
||||
ctx.pop()
|
||||
.expect("nix_libutil_init failed with bad ErrorContext");
|
||||
sys::nix_libstore_init(ctx.as_ptr());
|
||||
ctx.pop()
|
||||
.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");
|
||||
|
||||
// Try to get a valid store path by parsing
|
||||
// Note: This test is somewhat limited without a guaranteed valid path
|
||||
if let Ok(path) = StorePath::parse(&store, "/nix/store/00000000000000000000000000000000-test") {
|
||||
let cloned = path.clone();
|
||||
let path = StorePath::fake_path(&store).expect("Failed to create `StorePath::fake_path`");
|
||||
let cloned = path.clone();
|
||||
|
||||
// Assert that the cloned path has the same name as the original
|
||||
let original_name = path.name().expect("Failed to get original path name");
|
||||
let cloned_name = cloned.name().expect("Failed to get cloned path name");
|
||||
// Assert that the cloned path has the same name as the original
|
||||
let original_name = path.name().expect("Failed to get original path name");
|
||||
let cloned_name = cloned.name().expect("Failed to get cloned path name");
|
||||
|
||||
assert_eq!(
|
||||
original_name, cloned_name,
|
||||
"Cloned path should have the same name as original"
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
original_name, cloned_name,
|
||||
"Cloned path should have the same name as original"
|
||||
);
|
||||
}
|
||||
|
||||
// Note: test_realize is not included because it requires a valid store path
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@
|
|||
pub(crate) struct UserData<S, T> {
|
||||
pub inner: S,
|
||||
pub retval: T,
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub init_inner: bool,
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub init_retval: bool,
|
||||
}
|
||||
|
||||
impl<S, T> AsMut<UserData<S, T>> for UserData<S, T> {
|
||||
|
|
@ -11,30 +17,14 @@ 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> {
|
||||
/// # Warning
|
||||
///
|
||||
/// Ensure `self.retval` has been initialised before unwrapping!
|
||||
///
|
||||
pub unsafe fn unwrap(self) -> (S, T) {
|
||||
(self.inner, self.retval)
|
||||
}
|
||||
// pub unsafe fn unwrap(self) -> (S, T) {
|
||||
// (self.inner, self.retval)
|
||||
// }
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut Self {
|
||||
self as *mut Self
|
||||
|
|
@ -62,7 +52,6 @@ macro_rules! nonnull {
|
|||
}
|
||||
}};
|
||||
}
|
||||
use std::ffi::c_void;
|
||||
|
||||
pub(crate) use nonnull;
|
||||
|
||||
|
|
@ -146,7 +135,9 @@ macro_rules! nix_callback {
|
|||
|
||||
$function(__wrapper_callback, __state.as_mut_ptr(), &__ctx);
|
||||
|
||||
__ctx.pop().and_then(|_| unsafe { __state.assume_init().retval })
|
||||
// type annotations for compiler
|
||||
let __result: $ret = __ctx.pop().and_then(|_| unsafe { __state.assume_init().retval });
|
||||
__result
|
||||
}};
|
||||
}
|
||||
pub(crate) use nix_callback;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue