From ae19428cd54404668162dcfd0d6cf0b04de222ed Mon Sep 17 00:00:00 2001 From: _cry64 Date: Fri, 27 Mar 2026 15:35:02 +1000 Subject: [PATCH 1/6] finish ErrorContext::set_err --- nixide/src/errors/context.rs | 53 +++++++++++++++++----------------- nixide/src/errors/nix_error.rs | 15 ++++++++++ 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/nixide/src/errors/context.rs b/nixide/src/errors/context.rs index 39b1ea6..6ea266e 100644 --- a/nixide/src/errors/context.rs +++ b/nixide/src/errors/context.rs @@ -26,7 +26,7 @@ use std::ffi::c_void; use std::ptr::NonNull; use super::{NixError, NixideResult}; -use crate::stdext::CCharPtrExt as _; +use crate::stdext::{AsCPtr as _, CCharPtrExt as _}; use crate::sys; use crate::util::panic_issue_call_failed; use crate::util::wrap; @@ -62,8 +62,8 @@ use crate::util::wrappers::AsInnerPtr; /// ```c /// assert(*(nix_err*)ctx == NIX_OK); /// ``` +/// pub(crate) struct ErrorContext { - // XXX: TODO: add a RwLock to this (maybe Arc? or is that excessive?) inner: NonNull, } @@ -92,6 +92,7 @@ impl Into> for &ErrorContext { /// /// This function will panic in the event that `value != sys::nix_err_NIX_OK` /// but that `context.get_code() == sys::nix_err_NIX_OK` + /// fn into(self) -> NixideResult<()> { let inner = match self.get_err() { Some(err) => err, @@ -132,37 +133,22 @@ impl ErrorContext { /// /// Returns an error if no memory can be allocated for /// the underlying [sys::nix_c_context] struct. + /// pub fn new() -> Self { match NonNull::new(unsafe { sys::nix_c_context_create() }) { Some(inner) => ErrorContext { inner }, None => panic!("[nixide] CRITICAL FAILURE: Out-Of-Memory condition reached - `sys::nix_c_context_create` allocation failed!"), } - - // Initialize required libraries - // XXX: TODO: move this to a separate init function (maybe a Nix::init() function) - // unsafe { - // NixErrorCode::from( - // sys::nix_libutil_init(ctx.inner.as_ptr()), - // "nix_libutil_init", - // )?; - // NixErrorCode::from( - // sys::nix_libstore_init(ctx.inner.as_ptr()), - // "nix_libstore_init", - // )?; - // NixErrorCode::from( - // sys::nix_libexpr_init(ctx.inner.as_ptr()), - // "nix_libexpr_init", - // )?; - // }; } /// Check the error code and return an error if it's not `NIX_OK`. + /// pub fn peak(&self) -> NixideResult<()> { self.into() } - /// /// Equivalent to running `self.peak()` then `self.clear()` + /// pub fn pop(&mut self) -> NixideResult<()> { self.peak().and_then(|_| Ok(self.clear())) } @@ -204,24 +190,32 @@ impl ErrorContext { /// } /// ``` /// - pub fn set_err(&self, err: NixError, msg: &str) { + #[allow(unused)] + pub fn set_err(&self, err: NixError, msg: &str) -> NixideResult<()> { let ptr = unsafe { self.as_ptr() }; assert!(!ptr.is_null(), ""); - sys::nix_set_err_msg(ptr, err.into()) + unsafe { + sys::nix_set_err_msg(ptr, err.err_code(), msg.as_c_ptr()?); + } + + Ok(()) } /// Returns [None] if [self.code] is [sys::nix_err_NIX_OK], and [Some] otherwise. /// /// # Nix C++ API Internals + /// /// ```cpp /// nix_err nix_err_code(const nix_c_context * read_context) /// { /// return read_context->last_err_code; /// } /// ``` + /// /// This function **never fails**. - pub(super) fn get_err(&self) -> Option { + /// + fn get_err(&self) -> Option { let err = unsafe { sys::nix_err_code(self.as_ptr()) }; match err { @@ -233,6 +227,7 @@ impl ErrorContext { /// Returns [None] if [self.code] is [sys::nix_err_NIX_OK], and [Some] otherwise. /// /// # Nix C++ API Internals + /// /// ```cpp /// const char * nix_err_msg(nix_c_context * context, const nix_c_context * read_context, unsigned int * n) /// { @@ -249,6 +244,7 @@ impl ErrorContext { /// ``` /// /// # Note + /// /// On failure [sys::nix_err_name] does the following if the error /// has the error code [sys::nix_err_NIX_OK]: /// ```cpp @@ -257,7 +253,8 @@ impl ErrorContext { /// ``` /// Hence we can just test whether the returned pointer is a `NULL` pointer, /// and avoid passing in a [sys::nix_c_context] struct. - pub(super) fn get_msg(&self) -> Option { + /// + fn get_msg(&self) -> Option { let ctx = ErrorContext::new(); unsafe { // NOTE: an Err here only occurs when `self.get_code() == Ok(())` @@ -298,12 +295,14 @@ impl ErrorContext { /// `nix_set_err_msg` will cause undefined behaviour if `context` is a null pointer (see below) /// due to [https://github.com/rust-lang/rust-bindgen/issues/1208]. /// So we should never assigned it [std::ptr::null_mut]. + /// /// ```cpp /// if (context == nullptr) { /// throw nix::Error("Nix C api error: %s", msg); /// } /// ``` - pub(super) fn get_nix_err_name(&self) -> Option { + /// + fn get_nix_err_name(&self) -> Option { #[allow(unused_unsafe)] // XXX: TODO: remove this `unused_unsafe` unsafe { // NOTE: an Err here only occurs when "Last error was not a nix error" @@ -349,12 +348,14 @@ impl ErrorContext { /// `nix_set_err_msg` will cause undefined behaviour if `context` is a null pointer (see below) /// due to [https://github.com/rust-lang/rust-bindgen/issues/1208]. /// So we should never assigned it [std::ptr::null_mut]. + /// /// ```cpp /// if (context == nullptr) { /// throw nix::Error("Nix C api error: %s", msg); /// } /// ``` - pub(super) fn get_nix_err_info_msg(&self) -> Option { + /// + fn get_nix_err_info_msg(&self) -> Option { #[allow(unused_unsafe)] // XXX: TODO: remove this `unused_unsafe` unsafe { // NOTE: an Err here only occurs when "Last error was not a nix error" diff --git a/nixide/src/errors/nix_error.rs b/nixide/src/errors/nix_error.rs index 5e3938e..1d67312 100644 --- a/nixide/src/errors/nix_error.rs +++ b/nixide/src/errors/nix_error.rs @@ -113,3 +113,18 @@ impl Display for NixError { } } } + +impl NixError { + pub fn err_code(&self) -> sys::nix_err { + match self { + NixError::Overflow => sys::nix_err_NIX_ERR_OVERFLOW, + NixError::KeyNotFound(_) => sys::nix_err_NIX_ERR_NIX_ERROR, + NixError::ExprEval { + name: _, + info_msg: _, + } => sys::nix_err_NIX_ERR_NIX_ERROR, + NixError::Unknown => sys::nix_err_NIX_ERR_UNKNOWN, + NixError::Undocumented(err) => err.clone(), + } + } +} From e4fe62f7a6a19a4a0d712d526894606fe8ea6959 Mon Sep 17 00:00:00 2001 From: _cry64 Date: Fri, 27 Mar 2026 15:35:29 +1000 Subject: [PATCH 2/6] hide nixide-sys tests behind feature flags --- nixide-sys/tests/eval.rs | 1 + nixide-sys/tests/flake.rs | 1 + nixide-sys/tests/memory.rs | 1 + nixide-sys/tests/primop.rs | 1 + nixide-sys/tests/store.rs | 1 + 5 files changed, 5 insertions(+) diff --git a/nixide-sys/tests/eval.rs b/nixide-sys/tests/eval.rs index 742b4d0..c417850 100644 --- a/nixide-sys/tests/eval.rs +++ b/nixide-sys/tests/eval.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "nix-expr-c")] #![cfg(test)] use std::{ diff --git a/nixide-sys/tests/flake.rs b/nixide-sys/tests/flake.rs index 01fed21..d9f67c8 100644 --- a/nixide-sys/tests/flake.rs +++ b/nixide-sys/tests/flake.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "nix-flake-c")] #![cfg(test)] use std::ptr; diff --git a/nixide-sys/tests/memory.rs b/nixide-sys/tests/memory.rs index 229b6bd..4ac8702 100644 --- a/nixide-sys/tests/memory.rs +++ b/nixide-sys/tests/memory.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "nix-expr-c")] #![cfg(test)] use std::ffi::CString; diff --git a/nixide-sys/tests/primop.rs b/nixide-sys/tests/primop.rs index ecfacf8..257faaf 100644 --- a/nixide-sys/tests/primop.rs +++ b/nixide-sys/tests/primop.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "nix-expr-c")] #![cfg(test)] use std::{ diff --git a/nixide-sys/tests/store.rs b/nixide-sys/tests/store.rs index bb12a33..b1c8171 100644 --- a/nixide-sys/tests/store.rs +++ b/nixide-sys/tests/store.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "nix-store-c")] #![cfg(test)] use std::{ffi::CString, ptr}; From e77b246c8855b6bef339008aa3b4b2a7a3274316 Mon Sep 17 00:00:00 2001 From: _cry64 Date: Fri, 27 Mar 2026 15:35:48 +1000 Subject: [PATCH 3/6] export set_verbosity --- nixide/src/lib.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nixide/src/lib.rs b/nixide/src/lib.rs index dd127c6..2acbdd1 100644 --- a/nixide/src/lib.rs +++ b/nixide/src/lib.rs @@ -11,14 +11,13 @@ mod version; #[cfg(feature = "expr")] mod expr; +#[cfg(feature = "flake")] +mod flake; #[cfg(feature = "store")] mod store; -#[cfg(feature = "flake")] -mod flake; - pub use errors::{NixError, NixideError, NixideResult}; -pub use verbosity::NixVerbosity; +pub use verbosity::{set_verbosity, NixVerbosity}; pub use version::NixVersion; #[cfg(feature = "expr")] From 957910b21e62a0c4fce8b197127583ebeb07726b Mon Sep 17 00:00:00 2001 From: _cry64 Date: Fri, 27 Mar 2026 15:36:23 +1000 Subject: [PATCH 4/6] fix LazyArray --- nixide/src/expr/realised_string.rs | 5 ++- nixide/src/stdext/mod.rs | 2 +- nixide/src/util/lazy_array.rs | 54 ++++++------------------------ 3 files changed, 13 insertions(+), 48 deletions(-) diff --git a/nixide/src/expr/realised_string.rs b/nixide/src/expr/realised_string.rs index 5be5f8b..a3dbc7c 100644 --- a/nixide/src/expr/realised_string.rs +++ b/nixide/src/expr/realised_string.rs @@ -13,9 +13,9 @@ use crate::{EvalState, NixideResult, StorePath}; pub struct RealisedString { inner: NonNull, - // pub path: LazyCell StorePath>>, pub path: StorePath, - pub children: LazyArray StorePath>, usize) -> StorePath>>, + pub children: + LazyArray StorePath>, usize) -> StorePath>, } impl AsInnerPtr for RealisedString { @@ -88,7 +88,6 @@ impl RealisedString { Ok(Self { inner, path: Self::parse_path(inner.as_ptr(), state), - // children: LazyArray::new(size, delegate as fn(usize) -> StorePath), children: LazyArray:: StorePath>>::new( size, Box::new(delegate), diff --git a/nixide/src/stdext/mod.rs b/nixide/src/stdext/mod.rs index fe17913..d30c295 100644 --- a/nixide/src/stdext/mod.rs +++ b/nixide/src/stdext/mod.rs @@ -1,4 +1,4 @@ mod cchar_ptr_ext; -pub(crate) use cchar_ptr_ext::CCharPtrExt; +pub(crate) use cchar_ptr_ext::{AsCPtr, CCharPtrExt}; pub(crate) use stdext::*; diff --git a/nixide/src/util/lazy_array.rs b/nixide/src/util/lazy_array.rs index 2808314..6b4b1a5 100644 --- a/nixide/src/util/lazy_array.rs +++ b/nixide/src/util/lazy_array.rs @@ -1,12 +1,11 @@ -use std::cell::RefCell; -use std::rc::Rc; +use std::cell::{Ref, RefCell}; #[derive(Debug)] pub struct LazyArray where F: Fn(usize) -> T, { - inner: Rc>>>, + inner: RefCell>>, size: usize, delegate: F, } @@ -22,58 +21,25 @@ where } LazyArray { - inner: Rc::new(RefCell::new(vec)), + inner: RefCell::new(vec), size, delegate, } } - /// Returns `None` if `index < self.size` otherwise always succeeds + /// Returns `None` if `index >= self.size` otherwise always succeeds /// (unless of course the callback you supply panics). /// - // pub fn get(&mut self, index: usize) -> Option<&T> { - // // let x = self.inner.get(index).copied().and_then(|value| match value { - // // Some(value) => Some(value), - // // None => { - // // // store the value first - // // let value = (self.delegate)(index); - // // self.inner[index] = Some(value); + pub fn get<'a>(&'a mut self, index: usize) -> Option>> { + let borrowed = self.inner.borrow(); - // // // now get a reference to it - // // if let Some(v) = &self.inner[index] { - // // return Some(v); - // // } - // // None - // // } - // // }) - // match self.inner.clone().borrow().get(index) { - // Some(Some(value)) => Some(value), - // Some(None) => { - // let mut inner = self.inner.clone().borrow_mut(); - // // store the value first - // inner[index] = Some((self.delegate)(index)); - - // // now get a reference to it - // inner[index].as_ref() - // } - // None => None, - // } - // } - pub fn get(&mut self, index: usize) -> Option> { if index >= self.size { return None; + } else if borrowed[index].is_none() { + let value = (self.delegate)(index); + self.inner.borrow_mut()[index] = Some(value); } - // let inner = self.inner.borrow(); - if let Some(value) = self.inner.borrow()[index].as_ref() { - return Some(Rc::new(value)); - } - - // drop(inner); // explicitly drop the borrow - - let value = (self.delegate)(index); - self.inner.borrow_mut()[index] = Some(value); - - Some(Rc::new(self.inner.borrow()[index].unwrap())) + Some(Ref::map(borrowed, |v| &v[index])) } } From 841087c6c658badceb7b87e8d9ef9f4945a1f1bd Mon Sep 17 00:00:00 2001 From: _cry64 Date: Fri, 27 Mar 2026 15:36:38 +1000 Subject: [PATCH 5/6] dead code x_x --- nixide/src/stdext/cchar_ptr_ext.rs | 4 ++++ nixide/src/util/wrappers.rs | 3 +++ 2 files changed, 7 insertions(+) diff --git a/nixide/src/stdext/cchar_ptr_ext.rs b/nixide/src/stdext/cchar_ptr_ext.rs index 733ed98..0a91b86 100644 --- a/nixide/src/stdext/cchar_ptr_ext.rs +++ b/nixide/src/stdext/cchar_ptr_ext.rs @@ -6,8 +6,10 @@ use crate::errors::new_nixide_error; use crate::NixideResult; pub trait AsCPtr { + #[allow(unused)] fn as_c_ptr(&self) -> NixideResult<*const T>; + #[allow(unused)] fn into_c_ptr(self) -> NixideResult<*mut T>; } @@ -31,8 +33,10 @@ where } pub trait CCharPtrExt { + #[allow(unused)] fn to_utf8_string(self) -> NixideResult; + #[allow(unused)] fn to_utf8_string_n(self, n: usize) -> NixideResult; } diff --git a/nixide/src/util/wrappers.rs b/nixide/src/util/wrappers.rs index c3e4b07..938187c 100644 --- a/nixide/src/util/wrappers.rs +++ b/nixide/src/util/wrappers.rs @@ -6,6 +6,7 @@ pub trait AsInnerPtr { /// Although this function isn't inherently `unsafe`, it is /// marked as such intentionally to force calls to be wrapped /// in `unsafe` blocks for clarity. + #[allow(unused)] unsafe fn as_ptr(&self) -> *mut T; /// Returns a shared reference to the inner `libnix` C struct. @@ -17,6 +18,7 @@ pub trait AsInnerPtr { /// Although this function isn't inherently `unsafe`, it is /// marked as such intentionally to force calls to be wrapped /// in `unsafe` blocks for clarity. + #[allow(unused)] unsafe fn as_ref(&self) -> &T; /// Returns a unique reference to the inner `libnix` C struct. @@ -28,5 +30,6 @@ pub trait AsInnerPtr { /// Although this function isn't inherently `unsafe`, it is /// marked as such intentionally to force calls to be wrapped /// in `unsafe` blocks for clarity. + #[allow(unused)] unsafe fn as_mut(&mut self) -> &mut T; } From c15b02577702e43e335107157b2eac7822ed181e Mon Sep 17 00:00:00 2001 From: _cry64 Date: Fri, 27 Mar 2026 15:37:19 +1000 Subject: [PATCH 6/6] hide helix config --- .gitignore | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index e6857d8..d42ac36 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Nix -result -result-* +/result +/result-* # Rust /target + +# Helix +/.helix