Compare commits
No commits in common. "c15b02577702e43e335107157b2eac7822ed181e" and "5930db8233aa8fb384b873fe855b3b2980d8aea4" have entirely different histories.
c15b025777
...
5930db8233
14 changed files with 80 additions and 75 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -1,9 +1,6 @@
|
|||
# Nix
|
||||
/result
|
||||
/result-*
|
||||
result
|
||||
result-*
|
||||
|
||||
# Rust
|
||||
/target
|
||||
|
||||
# Helix
|
||||
/.helix
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![cfg(feature = "nix-expr-c")]
|
||||
#![cfg(test)]
|
||||
|
||||
use std::{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![cfg(feature = "nix-flake-c")]
|
||||
#![cfg(test)]
|
||||
|
||||
use std::ptr;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![cfg(feature = "nix-expr-c")]
|
||||
#![cfg(test)]
|
||||
|
||||
use std::ffi::CString;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![cfg(feature = "nix-expr-c")]
|
||||
#![cfg(test)]
|
||||
|
||||
use std::{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![cfg(feature = "nix-store-c")]
|
||||
#![cfg(test)]
|
||||
|
||||
use std::{ffi::CString, ptr};
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use std::ffi::c_void;
|
|||
use std::ptr::NonNull;
|
||||
|
||||
use super::{NixError, NixideResult};
|
||||
use crate::stdext::{AsCPtr as _, CCharPtrExt as _};
|
||||
use crate::stdext::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<RwLock>? or is that excessive?)
|
||||
inner: NonNull<sys::nix_c_context>,
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +92,6 @@ impl Into<NixideResult<()>> 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,
|
||||
|
|
@ -133,22 +132,37 @@ 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()`
|
||||
///
|
||||
/// Equivalent to running `self.peak()` then `self.clear()`
|
||||
pub fn pop(&mut self) -> NixideResult<()> {
|
||||
self.peak().and_then(|_| Ok(self.clear()))
|
||||
}
|
||||
|
|
@ -190,32 +204,24 @@ impl ErrorContext {
|
|||
/// }
|
||||
/// ```
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn set_err(&self, err: NixError, msg: &str) -> NixideResult<()> {
|
||||
pub fn set_err(&self, err: NixError, msg: &str) {
|
||||
let ptr = unsafe { self.as_ptr() };
|
||||
assert!(!ptr.is_null(), "");
|
||||
|
||||
unsafe {
|
||||
sys::nix_set_err_msg(ptr, err.err_code(), msg.as_c_ptr()?);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
sys::nix_set_err_msg(ptr, err.into())
|
||||
}
|
||||
|
||||
/// 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**.
|
||||
///
|
||||
fn get_err(&self) -> Option<sys::nix_err> {
|
||||
pub(super) fn get_err(&self) -> Option<sys::nix_err> {
|
||||
let err = unsafe { sys::nix_err_code(self.as_ptr()) };
|
||||
|
||||
match err {
|
||||
|
|
@ -227,7 +233,6 @@ 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)
|
||||
/// {
|
||||
|
|
@ -244,7 +249,6 @@ 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
|
||||
|
|
@ -253,8 +257,7 @@ 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.
|
||||
///
|
||||
fn get_msg(&self) -> Option<String> {
|
||||
pub(super) fn get_msg(&self) -> Option<String> {
|
||||
let ctx = ErrorContext::new();
|
||||
unsafe {
|
||||
// NOTE: an Err here only occurs when `self.get_code() == Ok(())`
|
||||
|
|
@ -295,14 +298,12 @@ 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);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
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 {
|
||||
// NOTE: an Err here only occurs when "Last error was not a nix error"
|
||||
|
|
@ -348,14 +349,12 @@ 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);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
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 {
|
||||
// NOTE: an Err here only occurs when "Last error was not a nix error"
|
||||
|
|
|
|||
|
|
@ -113,18 +113,3 @@ 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ use crate::{EvalState, NixideResult, StorePath};
|
|||
|
||||
pub struct RealisedString {
|
||||
inner: NonNull<sys::nix_realised_string>,
|
||||
// pub path: LazyCell<StorePath, Box<fn() -> StorePath>>,
|
||||
pub path: StorePath,
|
||||
pub children:
|
||||
LazyArray<StorePath, fn(&LazyArray<StorePath, fn(usize) -> StorePath>, usize) -> StorePath>,
|
||||
pub children: LazyArray<StorePath, fn(&LazyArray<StorePath, fn(usize) -> StorePath>, usize) -> StorePath>>,
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::nix_realised_string> for RealisedString {
|
||||
|
|
@ -88,6 +88,7 @@ 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, Box<dyn Fn(usize) -> StorePath>>::new(
|
||||
size,
|
||||
Box::new(delegate),
|
||||
|
|
|
|||
|
|
@ -11,13 +11,14 @@ 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::{set_verbosity, NixVerbosity};
|
||||
pub use verbosity::NixVerbosity;
|
||||
pub use version::NixVersion;
|
||||
|
||||
#[cfg(feature = "expr")]
|
||||
|
|
|
|||
|
|
@ -6,10 +6,8 @@ use crate::errors::new_nixide_error;
|
|||
use crate::NixideResult;
|
||||
|
||||
pub trait AsCPtr<T> {
|
||||
#[allow(unused)]
|
||||
fn as_c_ptr(&self) -> NixideResult<*const T>;
|
||||
|
||||
#[allow(unused)]
|
||||
fn into_c_ptr(self) -> NixideResult<*mut T>;
|
||||
}
|
||||
|
||||
|
|
@ -33,10 +31,8 @@ where
|
|||
}
|
||||
|
||||
pub trait CCharPtrExt {
|
||||
#[allow(unused)]
|
||||
fn to_utf8_string(self) -> NixideResult<String>;
|
||||
|
||||
#[allow(unused)]
|
||||
fn to_utf8_string_n(self, n: usize) -> NixideResult<String>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
mod cchar_ptr_ext;
|
||||
|
||||
pub(crate) use cchar_ptr_ext::{AsCPtr, CCharPtrExt};
|
||||
pub(crate) use cchar_ptr_ext::CCharPtrExt;
|
||||
pub(crate) use stdext::*;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use std::cell::{Ref, RefCell};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LazyArray<T, F>
|
||||
where
|
||||
F: Fn(usize) -> T,
|
||||
{
|
||||
inner: RefCell<Vec<Option<T>>>,
|
||||
inner: Rc<RefCell<Vec<Option<T>>>>,
|
||||
size: usize,
|
||||
delegate: F,
|
||||
}
|
||||
|
|
@ -21,25 +22,58 @@ where
|
|||
}
|
||||
|
||||
LazyArray {
|
||||
inner: RefCell::new(vec),
|
||||
inner: Rc::new(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<'a>(&'a mut self, index: usize) -> Option<Ref<'a, Option<T>>> {
|
||||
let borrowed = self.inner.borrow();
|
||||
// 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);
|
||||
|
||||
// // // 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<Rc<T>> {
|
||||
if index >= self.size {
|
||||
return None;
|
||||
} else if borrowed[index].is_none() {
|
||||
let value = (self.delegate)(index);
|
||||
self.inner.borrow_mut()[index] = Some(value);
|
||||
}
|
||||
|
||||
Some(Ref::map(borrowed, |v| &v[index]))
|
||||
// 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()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ pub trait AsInnerPtr<T> {
|
|||
/// 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.
|
||||
|
|
@ -18,7 +17,6 @@ pub trait AsInnerPtr<T> {
|
|||
/// 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.
|
||||
|
|
@ -30,6 +28,5 @@ pub trait AsInnerPtr<T> {
|
|||
/// 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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue