From ab9886281add228eac0e0eea576dfd2ae4675980 Mon Sep 17 00:00:00 2001 From: _cry64 Date: Wed, 25 Mar 2026 11:12:45 +1000 Subject: [PATCH] oh we're pushing --- nixide/src/store/mod.rs | 5 +-- nixide/src/store/path.rs | 17 ++++++--- nixide/src/store/tests.rs | 79 ++++++++++++++++++++++++++------------- nixide/src/util/wrap.rs | 33 ++++++---------- 4 files changed, 79 insertions(+), 55 deletions(-) diff --git a/nixide/src/store/mod.rs b/nixide/src/store/mod.rs index 96b29b5..7c057d7 100644 --- a/nixide/src/store/mod.rs +++ b/nixide/src/store/mod.rs @@ -197,10 +197,9 @@ impl Store { /// /// ```no_run /// # use std::sync::Arc; - /// # use nixide::{Context, Store}; + /// # use nixide::Store; /// # fn main() -> Result<(), Box> { - /// 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(()) /// # } diff --git a/nixide/src/store/path.rs b/nixide/src/store/path.rs index 5d18865..0c4e832 100644 --- a/nixide/src/store/path.rs +++ b/nixide/src/store/path.rs @@ -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 { + pub fn parse(store: &Store, path: &str) -> NixideResult { 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::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 { + pub fn name(&self) -> NixideResult { 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 { + pub fn real_path(&self, store: &Store) -> NixideResult { wrap::nix_pathbuf_callback!( |callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe { sys::nix_store_real_path( diff --git a/nixide/src/store/tests.rs b/nixide/src/store/tests.rs index 3e92b6c..d0b7744 100644 --- a/nixide/src/store/tests.rs +++ b/nixide/src/store/tests.rs @@ -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 diff --git a/nixide/src/util/wrap.rs b/nixide/src/util/wrap.rs index f26a2ac..595511b 100644 --- a/nixide/src/util/wrap.rs +++ b/nixide/src/util/wrap.rs @@ -3,6 +3,12 @@ pub(crate) struct UserData { pub inner: S, pub retval: T, + + #[cfg(debug_assertions)] + pub init_inner: bool, + + #[cfg(debug_assertions)] + pub init_retval: bool, } impl AsMut> for UserData { @@ -11,30 +17,14 @@ impl AsMut> for UserData { } } -// pub(crate) trait VoidPtrIsomorphism { -// fn as_void_ptr(self) -> *mut c_void; - -// fn from_void_ptr(ptr: *mut c_void) -> Self; -// } - -// impl VoidPtrIsomorphism for *mut UserData { -// 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 UserData { /// # 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;