Compare commits

...

3 commits

22 changed files with 220 additions and 261 deletions

View file

@ -24,6 +24,7 @@
allowUnfree = false; allowUnfree = false;
allowBroken = false; allowBroken = false;
overlays = builtins.attrValues self.overlays or {}; overlays = builtins.attrValues self.overlays or {};
# config.replaceStdenv = {pkgs}: with pkgs; llvmPackages_21.stdenv;
}; };
forAllSystems = f: forAllSystems = f:
@ -60,13 +61,19 @@
packages = with pkgs; [ packages = with pkgs; [
rustc rustc
llvmPackages.lld llvmPackages.lld
lldb llvmPackages.lldb
# lldb
cargo cargo
cargo-c cargo-c
cargo-llvm-cov cargo-llvm-cov
cargo-nextest cargo-nextest
clang # DEBUG
clang-tools # DEBUG
libcxx
rust-analyzer-unwrapped rust-analyzer-unwrapped
(rustfmt.override {asNightly = true;}) (rustfmt.override {asNightly = true;})
clippy clippy

View file

@ -1,5 +1,5 @@
use std::env;
use std::path::PathBuf; use std::path::PathBuf;
use std::{env, fs};
use bindgen::callbacks::ParseCallbacks; use bindgen::callbacks::ParseCallbacks;
@ -18,31 +18,26 @@ impl ParseCallbacks for DoxygenCallbacks {
} }
} }
const LIBS: &[&'static str] = &[
#[cfg(feature = "nix-util-c")]
"nix-util-c",
#[cfg(feature = "nix-store-c")]
"nix-store-c",
#[cfg(feature = "nix-expr-c")]
"nix-expr-c",
#[cfg(feature = "nix-fetchers-c")]
"nix-fetchers-c",
#[cfg(feature = "nix-flake-c")]
"nix-flake-c",
#[cfg(feature = "nix-main-c")]
"nix-main-c",
];
fn main() { fn main() {
// Invalidate the built crate whenever the wrapper changes // Invalidate the built crate if the binding headers change
println!("cargo::rerun-if-changed=include/nix-util.h"); // println!("cargo::rerun-if-changed=include");
println!("cargo::rerun-if-changed=include/nix-store.h");
println!("cargo::rerun-if-changed=include/nix-expr.h");
println!("cargo::rerun-if-changed=include/nix-fetchers.h");
println!("cargo::rerun-if-changed=include/nix-flake.h");
println!("cargo::rerun-if-changed=include/nix-main.h");
let libs = [ let lib_args: Vec<String> = LIBS
#[cfg(feature = "nix-util-c")]
"nix-util-c",
#[cfg(feature = "nix-store-c")]
"nix-store-c",
#[cfg(feature = "nix-expr-c")]
"nix-expr-c",
#[cfg(feature = "nix-fetchers-c")]
"nix-fetchers-c",
#[cfg(feature = "nix-flake-c")]
"nix-flake-c",
#[cfg(feature = "nix-main-c")]
"nix-main-c",
];
let lib_args: Vec<String> = libs
.iter() .iter()
.map(|&name| { .map(|&name| {
let lib = pkg_config::probe_library(name) let lib = pkg_config::probe_library(name)
@ -57,52 +52,35 @@ fn main() {
.map(|p| format!("-I{}", p.display())) .map(|p| format!("-I{}", p.display()))
}) })
.flatten() .flatten()
.chain(vec!["-Wall".to_owned(), "-xc++".to_owned()])
.collect(); .collect();
let mut builder = bindgen::Builder::default() let mut builder = bindgen::Builder::default()
// .clang_arg("") // libnix uses c++23
.clang_args(lib_args) .clang_args(lib_args)
// Invalidate the built crate when an included header file changes
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
// Add `doxygen_bindgen` callbacks // Add `doxygen_bindgen` callbacks
.parse_callbacks(Box::new(DoxygenCallbacks)) .parse_callbacks(Box::new(DoxygenCallbacks))
// Format generated bindings with rustfmt // Format generated bindings with rustfmt
.formatter(bindgen::Formatter::Rustfmt) .formatter(bindgen::Formatter::Rustfmt)
.rustfmt_configuration_file(std::fs::canonicalize(".rustfmt.toml").ok()); .rustfmt_configuration_file(std::fs::canonicalize("rustfmt.toml").ok());
// The input headers we would like to generate bindings for // Register the input headers we would like to generate bindings for
#[cfg(feature = "nix-util-c")] builder = LIBS
{ .iter()
builder = builder.header("include/nix-util.h") .map(|lib| {
} let path = format!("include/{}.h", lib.strip_suffix("-c").unwrap());
#[cfg(feature = "nix-store-c")] assert!(fs::exists(&path).unwrap());
{ // Invalidate the built crate if the binding headers change
builder = builder.header("include/nix-store.h") // println!("cargo::rerun-if-changed={path}");
} path
#[cfg(feature = "nix-expr-c")] })
{ .fold(builder, |builder, path| builder.header(path));
builder = builder.header("include/nix-expr.h")
}
#[cfg(feature = "nix-fetchers-c")]
{
builder = builder.header("include/nix-fetchers.h")
}
#[cfg(feature = "nix-flake-c")]
{
builder = builder.header("include/nix-flake.h")
}
#[cfg(feature = "nix-main-c")]
{
builder = builder.header("include/nix-main.h")
}
let bindings = builder
// Finish the builder and generate the bindings
.generate()
// Unwrap the Result and panic on failure
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file // Write the bindings to the $OUT_DIR/bindings.rs file
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let bindings = builder.generate().expect("Unable to generate bindings");
bindings bindings
.write_to_file(out_path.join("bindings.rs")) .write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!"); .expect("Couldn't write bindings!");

View file

@ -1,7 +1,8 @@
use std::ffi::{CString, c_void}; use std::cell::RefCell;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use crate::errors::new_nixide_error; use crate::stdext::AsCPtr as _;
use super::Value; use super::Value;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
@ -15,9 +16,9 @@ use crate::{NixideResult, Store};
/// This provides the main interface for evaluating Nix expressions /// This provides the main interface for evaluating Nix expressions
/// and creating values. /// and creating values.
pub struct EvalState { pub struct EvalState {
inner: NonNull<sys::EvalState>, inner: Rc<RefCell<NonNull<sys::EvalState>>>,
store: Store, store: Rc<RefCell<Store>>,
} }
// impl Clone for EvalState { // impl Clone for EvalState {
@ -39,31 +40,37 @@ pub struct EvalState {
impl AsInnerPtr<sys::EvalState> for EvalState { impl AsInnerPtr<sys::EvalState> for EvalState {
#[inline] #[inline]
unsafe fn as_ptr(&self) -> *mut sys::EvalState { unsafe fn as_ptr(&self) -> *mut sys::EvalState {
self.inner.as_ptr() self.inner.borrow().as_ptr()
} }
#[inline] #[inline]
unsafe fn as_ref(&self) -> &sys::EvalState { unsafe fn as_ref(&self) -> &sys::EvalState {
unsafe { self.inner.as_ref() } unsafe { self.inner.borrow().as_ref() }
} }
#[inline] #[inline]
unsafe fn as_mut(&mut self) -> &mut sys::EvalState { unsafe fn as_mut(&mut self) -> &mut sys::EvalState {
unsafe { self.inner.as_mut() } unsafe { self.inner.borrow_mut().as_mut() }
} }
} }
impl EvalState { impl EvalState {
/// Construct a new EvalState directly from its attributes /// Construct a new EvalState directly from its attributes
/// ///
pub(super) fn new(inner: NonNull<sys::EvalState>, store: &Store) -> Self { pub(super) fn from(inner: NonNull<sys::EvalState>, store: Rc<RefCell<Store>>) -> Self {
Self { Self {
inner, inner: Rc::new(RefCell::new(inner)),
store: store.clone(), store,
} }
} }
pub fn store_ref(&self) -> &Store { #[inline]
pub fn inner_ref(&self) -> &Rc<RefCell<NonNull<sys::EvalState>>> {
&self.inner
}
#[inline]
pub fn store_ref(&self) -> &Rc<RefCell<Store>> {
&self.store &self.store
} }
@ -77,9 +84,10 @@ impl EvalState {
/// # Errors /// # Errors
/// ///
/// Returns an error if evaluation fails. /// Returns an error if evaluation fails.
///
pub fn interpret(&self, expr: &str, path: &str) -> NixideResult<Value> { pub fn interpret(&self, expr: &str, path: &str) -> NixideResult<Value> {
let expr_c = CString::new(expr).or(Err(new_nixide_error!(StringNulByte)))?; let expr = expr.as_c_ptr()?;
let path_c = CString::new(path).or(Err(new_nixide_error!(StringNulByte)))?; let path = path.as_c_ptr()?;
// Allocate value for result // Allocate value for result
// XXX: TODO: create a method for this (``) // XXX: TODO: create a method for this (``)
@ -90,16 +98,10 @@ impl EvalState {
// Evaluate expression // Evaluate expression
wrap::nix_fn!(|ctx: &ErrorContext| unsafe { wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_expr_eval_from_string( sys::nix_expr_eval_from_string(ctx.as_ptr(), self.as_ptr(), expr, path, value.as_ptr());
ctx.as_ptr(),
self.as_ptr(),
expr_c.as_ptr(),
path_c.as_ptr(),
value.as_ptr(),
);
value value
}) })
.map(|ptr| Value::from((ptr, self))) .map(|ptr| Value::from((ptr, self.inner_ref().clone())))
} }
} }
@ -110,7 +112,3 @@ impl Drop for EvalState {
} }
} }
} }
// SAFETY: EvalState can be shared between threads
unsafe impl Send for EvalState {}
unsafe impl Sync for EvalState {}

View file

@ -1,5 +1,7 @@
use std::ffi::{CString, c_char, c_void}; use std::cell::RefCell;
use std::ffi::{CString, c_char};
use std::ptr::{self, NonNull}; use std::ptr::{self, NonNull};
use std::rc::Rc;
use super::EvalState; use super::EvalState;
#[cfg(feature = "flakes")] #[cfg(feature = "flakes")]
@ -16,40 +18,24 @@ use crate::util::{panic_issue_call_failed, wrap};
/// the evaluation state. /// the evaluation state.
/// ///
pub struct EvalStateBuilder { pub struct EvalStateBuilder {
inner: NonNull<sys::nix_eval_state_builder>, inner: Rc<RefCell<NonNull<sys::nix_eval_state_builder>>>,
store: Store, store: Rc<RefCell<Store>>,
} }
// impl Clone for EvalStateBuilder {
// fn clone(&self) -> Self {
// let inner = self.inner.clone();
//
// wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
// sys::nix_gc_incref(ctx.as_ptr(), self.as_ptr() as *mut c_void);
// })
// .unwrap();
//
// Self {
// inner,
// store: self.store.clone(),
// }
// }
// }
impl AsInnerPtr<sys::nix_eval_state_builder> for EvalStateBuilder { impl AsInnerPtr<sys::nix_eval_state_builder> for EvalStateBuilder {
#[inline] #[inline]
unsafe fn as_ptr(&self) -> *mut sys::nix_eval_state_builder { unsafe fn as_ptr(&self) -> *mut sys::nix_eval_state_builder {
self.inner.as_ptr() self.inner.borrow().as_ptr()
} }
#[inline] #[inline]
unsafe fn as_ref(&self) -> &sys::nix_eval_state_builder { unsafe fn as_ref(&self) -> &sys::nix_eval_state_builder {
unsafe { self.inner.as_ref() } unsafe { self.inner.borrow().as_ref() }
} }
#[inline] #[inline]
unsafe fn as_mut(&mut self) -> &mut sys::nix_eval_state_builder { unsafe fn as_mut(&mut self) -> &mut sys::nix_eval_state_builder {
unsafe { self.inner.as_mut() } unsafe { self.inner.borrow_mut().as_mut() }
} }
} }
@ -64,14 +50,14 @@ impl EvalStateBuilder {
/// ///
/// Returns an error if the builder cannot be created. /// Returns an error if the builder cannot be created.
/// ///
pub fn new(store: &Store) -> NixideResult<Self> { pub fn new(store: Rc<RefCell<Store>>) -> NixideResult<Self> {
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_eval_state_builder_new(ctx.as_ptr(), store.as_ptr()) sys::nix_eval_state_builder_new(ctx.as_ptr(), store.borrow().as_ptr())
})?; })?;
Ok(EvalStateBuilder { Ok(EvalStateBuilder {
inner, inner: Rc::new(RefCell::new(inner)),
store: store.clone(), store,
}) })
} }
@ -87,7 +73,7 @@ impl EvalStateBuilder {
sys::nix_eval_state_build(ctx.as_ptr(), self.as_ptr()) sys::nix_eval_state_build(ctx.as_ptr(), self.as_ptr())
})?; })?;
Ok(EvalState::new(inner, &self.store)) Ok(EvalState::from(inner, self.store.clone()))
} }
// XXX: TODO: use `flakes()` instead // XXX: TODO: use `flakes()` instead

View file

@ -1,15 +1,15 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::ffi::{c_char, c_void}; use std::ffi::c_char;
use std::ptr::NonNull; use std::ptr::NonNull;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::expr::values::NixString; use crate::expr::values::NixString;
use crate::stdext::CCharPtrExt; use crate::stdext::CCharPtrExt;
use crate::sys;
use crate::util::LazyArray; use crate::util::LazyArray;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
use crate::util::{panic_issue_call_failed, wrap}; use crate::util::{panic_issue_call_failed, wrap};
use crate::{EvalState, NixideResult, StorePath}; use crate::{EvalState, NixideResult, StorePath};
use crate::{Store, sys};
pub struct RealisedString<'a> { pub struct RealisedString<'a> {
inner: RefCell<NonNull<sys::nix_realised_string>>, inner: RefCell<NonNull<sys::nix_realised_string>>,
@ -17,23 +17,6 @@ pub struct RealisedString<'a> {
pub children: LazyArray<StorePath, Box<dyn Fn(usize) -> StorePath + 'a>>, pub children: LazyArray<StorePath, Box<dyn Fn(usize) -> StorePath + 'a>>,
} }
// impl<'a> Clone for RealisedString<'a> {
// fn clone(&self) -> Self {
// let inner = self.inner.clone();
// wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
// sys::nix_gc_incref(ctx.as_ptr(), self.as_ptr() as *mut c_void);
// })
// .unwrap();
// Self {
// inner,
// path: self.path.clone(),
// children: self.children,
// }
// }
// }
impl<'a> AsInnerPtr<sys::nix_realised_string> for RealisedString<'a> { impl<'a> AsInnerPtr<sys::nix_realised_string> for RealisedString<'a> {
#[inline] #[inline]
unsafe fn as_ptr(&self) -> *mut sys::nix_realised_string { unsafe fn as_ptr(&self) -> *mut sys::nix_realised_string {
@ -63,7 +46,7 @@ impl<'a> RealisedString<'a> {
/// Realise a string context. /// Realise a string context.
/// ///
/// This will /// This will
/// - realise the store paths referenced by the string's context, and /// - realise the store paths referenced by the string's content, and
/// - perform the replacement of placeholders. /// - perform the replacement of placeholders.
/// - create temporary garbage collection roots for the store paths, for /// - create temporary garbage collection roots for the store paths, for
/// the lifetime of the current process. /// the lifetime of the current process.
@ -77,9 +60,6 @@ impl<'a> RealisedString<'a> {
/// You should set this to true when this call is part of a primop. /// You should set this to true when this call is part of a primop.
/// You should set this to false when building for your application's purpose. /// You should set this to false when building for your application's purpose.
/// ///
/// # Returns
///
/// NULL if failed, or a new nix_realised_string, which must be freed with nix_realised_string_free
pub fn new(value: &NixString, state: &'a EvalState) -> NixideResult<RealisedString<'a>> { pub fn new(value: &NixString, state: &'a EvalState) -> NixideResult<RealisedString<'a>> {
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_string_realise( sys::nix_string_realise(
@ -89,21 +69,20 @@ impl<'a> RealisedString<'a> {
false, // don't copy more false, // don't copy more
) )
})?; })?;
let cell = RefCell::new(inner);
let size = unsafe { sys::nix_realised_string_get_store_path_count(inner.as_ptr()) }; let size = unsafe { sys::nix_realised_string_get_store_path_count(inner.as_ptr()) };
Ok(Self { Ok(Self {
inner: cell, inner: RefCell::new(inner),
path: Self::parse_path(inner.as_ptr(), state), path: Self::parse_path(inner.as_ptr(), &state.store_ref().borrow()),
children: LazyArray::new( children: LazyArray::new(
size, size,
Box::new(|_| StorePath::fake_path(state.store_ref()).unwrap()), Box::new(|_| StorePath::fake_path(&state.store_ref().borrow()).unwrap()),
), ),
}) })
} }
fn parse_path(realised_string: *mut sys::nix_realised_string, state: &EvalState) -> StorePath { fn parse_path(realised_string: *mut sys::nix_realised_string, store: &Store) -> StorePath {
let buffer_ptr = unsafe { sys::nix_realised_string_get_buffer_start(realised_string) }; let buffer_ptr = unsafe { sys::nix_realised_string_get_buffer_start(realised_string) };
let buffer_size = unsafe { sys::nix_realised_string_get_buffer_size(realised_string) }; let buffer_size = unsafe { sys::nix_realised_string_get_buffer_size(realised_string) };
@ -115,7 +94,7 @@ impl<'a> RealisedString<'a> {
err err
) )
}); });
StorePath::parse(state.store_ref(), &path_str).unwrap_or_else(|err| { StorePath::parse(store, &path_str).unwrap_or_else(|err| {
panic_issue_call_failed!( panic_issue_call_failed!(
"`sys::nix_realised_string_get_buffer_(start|size)` invalid store path ({})", "`sys::nix_realised_string_get_buffer_(start|size)` invalid store path ({})",
err err

View file

@ -1,5 +1,3 @@
use std::rc::Rc;
use serial_test::serial; use serial_test::serial;
use super::{EvalStateBuilder, Value}; use super::{EvalStateBuilder, Value};
@ -8,19 +6,18 @@ use crate::Store;
#[test] #[test]
#[serial] #[serial]
fn test_eval_state_builder() { fn test_eval_state_builder() {
let store = Rc::new(Store::default().expect("Failed to open store")); let store = Store::default().expect("Failed to open store");
let _state = EvalStateBuilder::new(&store) let _state = EvalStateBuilder::new(store.clone())
.expect("Failed to create builder") .expect("Failed to create builder")
.build() .build()
.expect("Failed to build state"); .expect("Failed to build state");
// State should be dropped automatically
} }
#[test] #[test]
#[serial] #[serial]
fn test_simple_evaluation() { fn test_simple_evaluation() {
let store = Rc::new(Store::default().expect("Failed to open store")); let store = Store::default().expect("Failed to open store");
let state = EvalStateBuilder::new(&store) let state = EvalStateBuilder::new(store.clone())
.expect("Failed to create builder") .expect("Failed to create builder")
.build() .build()
.expect("Failed to build state"); .expect("Failed to build state");
@ -41,7 +38,7 @@ fn test_simple_evaluation() {
#[serial] #[serial]
fn test_value_types() { fn test_value_types() {
let store = Store::default().expect("Failed to open store"); let store = Store::default().expect("Failed to open store");
let state = EvalStateBuilder::new(&store) let state = EvalStateBuilder::new(store.clone())
.expect("Failed to create builder") .expect("Failed to create builder")
.build() .build()
.expect("Failed to build state"); .expect("Failed to build state");
@ -84,7 +81,7 @@ fn test_value_types() {
#[serial] #[serial]
fn test_value_formatting() { fn test_value_formatting() {
let store = Store::default().expect("Failed to open store"); let store = Store::default().expect("Failed to open store");
let state = EvalStateBuilder::new(&store) let state = EvalStateBuilder::new(store.clone())
.expect("Failed to create builder") .expect("Failed to create builder")
.build() .build()
.expect("Failed to build state"); .expect("Failed to build state");

View file

@ -1,17 +1,19 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::{self, NonNull}; use std::ptr::{self, NonNull};
use std::rc::Rc;
use super::{NixThunk, NixValue, Value}; use super::{NixThunk, NixValue, Value};
use crate::NixError;
use crate::errors::{ErrorContext, NixideError}; use crate::errors::{ErrorContext, NixideError};
use crate::stdext::{AsCPtr, CCharPtrExt}; use crate::stdext::{AsCPtr, CCharPtrExt};
use crate::sys; use crate::sys;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
use crate::util::{panic_issue_call_failed, wrap}; use crate::util::{panic_issue_call_failed, wrap};
use crate::{EvalState, NixError};
pub struct NixAttrs { pub struct NixAttrs {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
len: u32, len: u32,
} }
@ -76,17 +78,13 @@ impl NixValue for NixAttrs {
sys::ValueType_NIX_TYPE_ATTRS sys::ValueType_NIX_TYPE_ATTRS
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
let len = wrap::nix_fn!(|ctx: &ErrorContext| unsafe { let len = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_attrs_size(ctx.as_ptr(), inner.as_ptr()) sys::nix_get_attrs_size(ctx.as_ptr(), inner.as_ptr())
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
Self { Self { inner, state, len }
inner,
state: state.clone(),
len,
}
} }
} }
@ -107,7 +105,7 @@ impl NixAttrs {
sys::nix_get_attr_byidx( sys::nix_get_attr_byidx(
ctx.as_ptr(), ctx.as_ptr(),
self.as_ptr(), self.as_ptr(),
self.state.as_ptr(), self.state.borrow().as_ptr(),
index, index,
name_ptr, name_ptr,
) )
@ -118,7 +116,7 @@ impl NixAttrs {
.to_utf8_string() .to_utf8_string()
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
let value = Value::from((inner, &self.state)); let value = Value::from((inner, self.state.clone()));
Some((name, value)) Some((name, value))
} }
@ -134,7 +132,7 @@ impl NixAttrs {
sys::nix_get_attr_byidx_lazy( sys::nix_get_attr_byidx_lazy(
ctx.as_ptr(), ctx.as_ptr(),
self.as_ptr(), self.as_ptr(),
self.state.as_ptr(), self.state.borrow().as_ptr(),
index, index,
name_ptr, name_ptr,
) )
@ -145,7 +143,7 @@ impl NixAttrs {
.to_utf8_string() .to_utf8_string()
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
let value = <NixThunk as NixValue>::from(inner, &self.state); let value = <NixThunk as NixValue>::from(inner, self.state.clone());
Some((name, value)) Some((name, value))
} }
@ -156,7 +154,12 @@ impl NixAttrs {
} }
let name_ptr = wrap::nix_fn!(|ctx: &ErrorContext| unsafe { let name_ptr = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_attr_name_byidx(ctx.as_ptr(), self.as_ptr(), self.state.as_ptr(), index) sys::nix_get_attr_name_byidx(
ctx.as_ptr(),
self.as_ptr(),
self.state.borrow().as_ptr(),
index,
)
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
@ -175,7 +178,7 @@ impl NixAttrs {
sys::nix_get_attr_byname( sys::nix_get_attr_byname(
ctx.as_ptr(), ctx.as_ptr(),
self.as_ptr(), self.as_ptr(),
self.state.as_ptr(), self.state.borrow().as_ptr(),
name.as_ref() name.as_ref()
.into_c_ptr() .into_c_ptr()
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)), .unwrap_or_else(|err| panic_issue_call_failed!("{}", err)),
@ -183,7 +186,7 @@ impl NixAttrs {
}); });
match result { match result {
Ok(inner) => Some(Value::from((inner, &self.state))), Ok(inner) => Some(Value::from((inner, self.state.clone()))),
Err(NixideError::NixError { Err(NixideError::NixError {
err: NixError::KeyNotFound(_), err: NixError::KeyNotFound(_),
@ -201,7 +204,7 @@ impl NixAttrs {
sys::nix_get_attr_byname_lazy( sys::nix_get_attr_byname_lazy(
ctx.as_ptr(), ctx.as_ptr(),
self.as_ptr(), self.as_ptr(),
self.state.as_ptr(), self.state.borrow().as_ptr(),
name.as_ref() name.as_ref()
.into_c_ptr() .into_c_ptr()
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)), .unwrap_or_else(|err| panic_issue_call_failed!("{}", err)),
@ -209,7 +212,7 @@ impl NixAttrs {
}); });
match result { match result {
Ok(inner) => Some(<NixThunk as NixValue>::from(inner, &self.state)), Ok(inner) => Some(<NixThunk as NixValue>::from(inner, self.state.clone())),
Err(NixideError::NixError { Err(NixideError::NixError {
err: NixError::KeyNotFound(_), err: NixError::KeyNotFound(_),

View file

@ -1,16 +1,18 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use super::NixValue; use super::NixValue;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::sys;
use crate::util::panic_issue_call_failed; use crate::util::panic_issue_call_failed;
use crate::util::wrap; use crate::util::wrap;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
use crate::{EvalState, sys};
pub struct NixBool { pub struct NixBool {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
value: bool, value: bool,
} }
@ -75,7 +77,7 @@ impl NixValue for NixBool {
sys::ValueType_NIX_TYPE_BOOL sys::ValueType_NIX_TYPE_BOOL
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe { let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_bool(ctx.as_ptr(), inner.as_ptr()) sys::nix_get_bool(ctx.as_ptr(), inner.as_ptr())
}) })
@ -85,7 +87,7 @@ impl NixValue for NixBool {
Self { Self {
inner, inner,
state: state.clone(), state,
value, value,
} }
} }

View file

@ -1,8 +1,9 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use super::NixValue; use super::NixValue;
use crate::EvalState;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::sys; use crate::sys;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
@ -10,7 +11,7 @@ use crate::util::{panic_issue_call_failed, wrap};
pub struct NixFloat { pub struct NixFloat {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
value: f64, value: f64,
} }
@ -75,7 +76,7 @@ impl NixValue for NixFloat {
sys::ValueType_NIX_TYPE_FLOAT sys::ValueType_NIX_TYPE_FLOAT
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe { let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_float(ctx.as_ptr(), inner.as_ptr()) sys::nix_get_float(ctx.as_ptr(), inner.as_ptr())
}) })
@ -85,7 +86,7 @@ impl NixValue for NixFloat {
Self { Self {
inner, inner,
state: state.clone(), state,
value, value,
} }
} }

View file

@ -1,16 +1,18 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use super::{NixValue, Value}; use super::{NixValue, Value};
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::stdext::SliceExt; use crate::stdext::SliceExt;
use crate::sys;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
use crate::util::{panic_issue_call_failed, wrap}; use crate::util::{panic_issue_call_failed, wrap};
use crate::{EvalState, sys};
pub struct NixFunction { pub struct NixFunction {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
} }
impl Clone for NixFunction { impl Clone for NixFunction {
@ -73,11 +75,8 @@ impl NixValue for NixFunction {
sys::ValueType_NIX_TYPE_FUNCTION sys::ValueType_NIX_TYPE_FUNCTION
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
Self { Self { inner, state }
inner,
state: state.clone(),
}
} }
} }
@ -87,14 +86,14 @@ impl NixFunction {
T: NixValue, T: NixValue,
{ {
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_alloc_value(ctx.as_ptr(), self.state.as_ptr()) sys::nix_alloc_value(ctx.as_ptr(), self.state.borrow().as_ptr())
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
wrap::nix_fn!(|ctx: &ErrorContext| unsafe { wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_value_call( sys::nix_value_call(
ctx.as_ptr(), ctx.as_ptr(),
self.state.as_ptr(), self.state.borrow().as_ptr(),
self.as_ptr(), self.as_ptr(),
arg.as_ptr(), arg.as_ptr(),
inner.as_ptr(), inner.as_ptr(),
@ -102,7 +101,7 @@ impl NixFunction {
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
Value::from((inner, &self.state)) Value::from((inner, self.state.clone()))
} }
pub fn call_many<T>(&self, args: &[&T]) -> Value pub fn call_many<T>(&self, args: &[&T]) -> Value
@ -110,14 +109,14 @@ impl NixFunction {
T: NixValue, T: NixValue,
{ {
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_alloc_value(ctx.as_ptr(), self.state.as_ptr()) sys::nix_alloc_value(ctx.as_ptr(), self.state.borrow().as_ptr())
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
wrap::nix_fn!(|ctx: &ErrorContext| unsafe { wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_value_call_multi( sys::nix_value_call_multi(
ctx.as_ptr(), ctx.as_ptr(),
self.state.as_ptr(), self.state.borrow().as_ptr(),
self.as_ptr(), self.as_ptr(),
args.len(), args.len(),
args.into_c_array(), args.into_c_array(),
@ -126,7 +125,7 @@ impl NixFunction {
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
Value::from((inner, &self.state)) Value::from((inner, self.state.clone()))
} }
} }

View file

@ -1,8 +1,9 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use super::NixValue; use super::NixValue;
use crate::EvalState;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::sys; use crate::sys;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
@ -10,7 +11,7 @@ use crate::util::{panic_issue_call_failed, wrap};
pub struct NixInt { pub struct NixInt {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
value: i64, value: i64,
} }
@ -75,7 +76,7 @@ impl NixValue for NixInt {
sys::ValueType_NIX_TYPE_INT sys::ValueType_NIX_TYPE_INT
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe { let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_int(ctx.as_ptr(), inner.as_ptr()) sys::nix_get_int(ctx.as_ptr(), inner.as_ptr())
}) })
@ -83,7 +84,7 @@ impl NixValue for NixInt {
Self { Self {
inner, inner,
state: state.clone(), state,
value, value,
} }
} }

View file

@ -1,8 +1,9 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use super::{NixThunk, NixValue, Value}; use super::{NixThunk, NixValue, Value};
use crate::EvalState;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::sys; use crate::sys;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
@ -10,7 +11,7 @@ use crate::util::{panic_issue_call_failed, wrap};
pub struct NixList { pub struct NixList {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
} }
impl Clone for NixList { impl Clone for NixList {
@ -73,11 +74,8 @@ impl NixValue for NixList {
sys::ValueType_NIX_TYPE_LIST sys::ValueType_NIX_TYPE_LIST
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
Self { Self { inner, state }
inner,
state: state.clone(),
}
} }
} }
@ -116,19 +114,29 @@ impl NixList {
pub fn get(&self, index: u32) -> Value { pub fn get(&self, index: u32) -> Value {
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_list_byidx(ctx.as_ptr(), self.as_ptr(), self.state.as_ptr(), index) sys::nix_get_list_byidx(
ctx.as_ptr(),
self.as_ptr(),
self.state.borrow().as_ptr(),
index,
)
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
Value::from((inner, &self.state)) Value::from((inner, self.state.clone()))
} }
pub fn get_lazy(&self, index: u32) -> NixThunk { pub fn get_lazy(&self, index: u32) -> NixThunk {
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_list_byidx_lazy(ctx.as_ptr(), self.as_ptr(), self.state.as_ptr(), index) sys::nix_get_list_byidx_lazy(
ctx.as_ptr(),
self.as_ptr(),
self.state.borrow().as_ptr(),
index,
)
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
<NixThunk as NixValue>::from(inner, &self.state) <NixThunk as NixValue>::from(inner, self.state.clone())
} }
} }

View file

@ -23,10 +23,11 @@ pub use path::NixPath;
pub use string::NixString; pub use string::NixString;
pub use thunk::NixThunk; pub use thunk::NixThunk;
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use crate::EvalState;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::sys; use crate::sys;
use crate::sys::{ use crate::sys::{
@ -43,7 +44,7 @@ pub trait NixValue: Clone + Drop + Display + Debug + AsInnerPtr<sys::nix_value>
fn type_id(&self) -> sys::ValueType; fn type_id(&self) -> sys::ValueType;
/// TODO /// TODO
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self; fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self;
} }
/// A Nix value /// A Nix value
@ -109,12 +110,22 @@ pub enum Value {
// Failed(NixFailed), // Failed(NixFailed),
} }
impl From<(NonNull<sys::nix_value>, &EvalState)> for Value { impl
fn from(value: (NonNull<sys::nix_value>, &EvalState)) -> Self { From<(
NonNull<sys::nix_value>,
Rc<RefCell<NonNull<sys::EvalState>>>,
)> for Value
{
fn from(
value: (
NonNull<sys::nix_value>,
Rc<RefCell<NonNull<sys::EvalState>>>,
),
) -> Self {
let (inner, state) = value; let (inner, state) = value;
wrap::nix_fn!(|ctx: &ErrorContext| unsafe { wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_value_force(ctx.as_ptr(), state.as_ptr(), inner.as_ptr()) sys::nix_value_force(ctx.as_ptr(), state.borrow().as_ptr(), inner.as_ptr())
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));

View file

@ -1,8 +1,9 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use super::NixValue; use super::NixValue;
use crate::EvalState;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::sys; use crate::sys;
use crate::util::wrap; use crate::util::wrap;
@ -10,7 +11,7 @@ use crate::util::wrappers::AsInnerPtr;
pub struct NixNull { pub struct NixNull {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
} }
impl Clone for NixNull { impl Clone for NixNull {
@ -73,10 +74,7 @@ impl NixValue for NixNull {
sys::ValueType_NIX_TYPE_NULL sys::ValueType_NIX_TYPE_NULL
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
Self { Self { inner, state }
inner,
state: state.clone(),
}
} }
} }

View file

@ -1,18 +1,20 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::path::PathBuf; use std::path::PathBuf;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use super::NixValue; use super::NixValue;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::stdext::CCharPtrExt; use crate::stdext::CCharPtrExt;
use crate::sys;
use crate::util::panic_issue_call_failed; use crate::util::panic_issue_call_failed;
use crate::util::wrap; use crate::util::wrap;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
use crate::{EvalState, sys};
pub struct NixPath { pub struct NixPath {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
value: PathBuf, value: PathBuf,
} }
@ -77,7 +79,7 @@ impl NixValue for NixPath {
sys::ValueType_NIX_TYPE_PATH sys::ValueType_NIX_TYPE_PATH
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe { let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_path_string(ctx.as_ptr(), inner.as_ptr()) sys::nix_get_path_string(ctx.as_ptr(), inner.as_ptr())
}) })
@ -87,7 +89,7 @@ impl NixValue for NixPath {
Self { Self {
inner, inner,
state: state.clone(), state,
value, value,
} }
} }

View file

@ -1,16 +1,19 @@
use std::cell::RefCell;
use std::ffi::c_void;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use super::NixValue; use super::NixValue;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::sys;
use crate::util::panic_issue_call_failed; use crate::util::panic_issue_call_failed;
use crate::util::wrap; use crate::util::wrap;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
use crate::{EvalState, sys};
pub struct NixString { pub struct NixString {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
value: String, value: String,
} }
@ -75,7 +78,7 @@ impl NixValue for NixString {
sys::ValueType_NIX_TYPE_STRING sys::ValueType_NIX_TYPE_STRING
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
let value = wrap::nix_string_callback!( let value = wrap::nix_string_callback!(
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe { |callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
sys::nix_get_string( sys::nix_get_string(
@ -90,7 +93,7 @@ impl NixValue for NixString {
Self { Self {
inner, inner,
state: state.clone(), state,
value, value,
} }
} }

View file

@ -1,8 +1,9 @@
use std::cell::RefCell;
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc;
use super::{NixValue, Value}; use super::{NixValue, Value};
use crate::EvalState;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
use crate::sys; use crate::sys;
use crate::util::wrappers::AsInnerPtr; use crate::util::wrappers::AsInnerPtr;
@ -10,7 +11,7 @@ use crate::util::{panic_issue_call_failed, wrap};
pub struct NixThunk { pub struct NixThunk {
inner: NonNull<sys::nix_value>, inner: NonNull<sys::nix_value>,
state: EvalState, state: Rc<RefCell<NonNull<sys::EvalState>>>,
} }
impl Clone for NixThunk { impl Clone for NixThunk {
@ -73,21 +74,22 @@ impl NixValue for NixThunk {
sys::ValueType_NIX_TYPE_THUNK sys::ValueType_NIX_TYPE_THUNK
} }
fn from(inner: NonNull<sys::nix_value>, state: &EvalState) -> Self { fn from(inner: NonNull<sys::nix_value>, state: Rc<RefCell<NonNull<sys::EvalState>>>) -> Self {
Self { Self { inner, state }
inner,
state: state.clone(),
}
} }
} }
impl NixThunk { impl NixThunk {
pub fn eval(self) -> Value { pub fn eval(self) -> Value {
wrap::nix_fn!(|ctx: &ErrorContext| unsafe { wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_value_force(ctx.as_ptr(), self.state.as_ptr(), self.inner.as_ptr()) sys::nix_value_force(
ctx.as_ptr(),
self.state.borrow().as_ptr(),
self.inner.as_ptr(),
)
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)); .unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
Value::from((self.inner, &self.state)) Value::from((self.inner, self.state.clone()))
} }
} }

View file

@ -1,4 +1,3 @@
use std::ffi::c_void;
use std::ptr::NonNull; use std::ptr::NonNull;
use crate::NixideResult; use crate::NixideResult;

View file

@ -1,4 +1,3 @@
use std::ffi::c_void;
use std::ptr::NonNull; use std::ptr::NonNull;
use crate::NixideResult; use crate::NixideResult;
@ -20,19 +19,6 @@ impl Drop for FlakeSettings {
} }
} }
// impl Clone for FlakeSettings {
// fn clone(&self) -> Self {
// let inner = self.inner.clone();
//
// wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
// sys::nix_gc_incref(ctx.as_ptr(), self.as_ptr() as *mut c_void);
// })
// .unwrap();
//
// Self { inner }
// }
// }
impl AsInnerPtr<sys::nix_flake_settings> for FlakeSettings { impl AsInnerPtr<sys::nix_flake_settings> for FlakeSettings {
#[inline] #[inline]
unsafe fn as_ptr(&self) -> *mut sys::nix_flake_settings { unsafe fn as_ptr(&self) -> *mut sys::nix_flake_settings {

View file

@ -1,6 +1,5 @@
// XXX: TODO: find a way to read directly from FlakeSettings and FetchersSettings (the C++ classes) // XXX: TODO: find a way to read directly from FlakeSettings and FetchersSettings (the C++ classes)
use std::ffi::c_void;
use std::ptr::NonNull; use std::ptr::NonNull;
use super::{FetchersSettings, FlakeLockFlags, FlakeReference, FlakeSettings}; use super::{FetchersSettings, FlakeLockFlags, FlakeReference, FlakeSettings};
@ -130,8 +129,8 @@ mod tests {
fn flake_settings_getflake_exists() { fn flake_settings_getflake_exists() {
init(); init();
let store = Store::default().expect("Failed to open store connection"); let store_ref = Store::default().expect("Failed to open store connection");
let state = EvalStateBuilder::new(&store) let state = EvalStateBuilder::new(store_ref.clone())
.unwrap() .unwrap()
.flakes() .flakes()
.unwrap() .unwrap()
@ -165,10 +164,10 @@ mod tests {
) )
.unwrap(); .unwrap();
let store = Store::default().unwrap(); let store_ref = Store::default().unwrap();
let flake_settings = FlakeSettings::new().unwrap(); let flake_settings = FlakeSettings::new().unwrap();
let mut eval_state = EvalStateBuilder::new(&store) let mut eval_state = EvalStateBuilder::new(store_ref.clone())
.unwrap() .unwrap()
.set_flake_settings(&flake_settings) .set_flake_settings(&flake_settings)
.unwrap() .unwrap()
@ -214,10 +213,10 @@ mod tests {
fn flake_lock_load_flake_with_flags() { fn flake_lock_load_flake_with_flags() {
init(); init();
let store = Store::default().unwrap(); let store_ref = Store::default().unwrap();
let fetchers_settings = FetchersSettings::new().unwrap(); let fetchers_settings = FetchersSettings::new().unwrap();
let flake_settings = FlakeSettings::new().unwrap(); let flake_settings = FlakeSettings::new().unwrap();
let mut eval_state = EvalStateBuilder::new(&store) let mut eval_state = EvalStateBuilder::new(store_ref.clone())
.unwrap() .unwrap()
.set_flake_settings(&flake_settings) .set_flake_settings(&flake_settings)
.unwrap() .unwrap()

View file

@ -7,9 +7,11 @@ mod tests;
mod path; mod path;
pub use path::*; pub use path::*;
use std::cell::RefCell;
use std::ffi::{c_char, c_void}; use std::ffi::{c_char, c_void};
use std::path::PathBuf; use std::path::PathBuf;
use std::ptr::{NonNull, null, null_mut}; use std::ptr::{NonNull, null, null_mut};
use std::rc::Rc;
use crate::NixideResult; use crate::NixideResult;
use crate::errors::ErrorContext; use crate::errors::ErrorContext;
@ -68,24 +70,24 @@ impl Store {
/// ///
/// Returns an error if the store cannot be opened. /// Returns an error if the store cannot be opened.
/// ///
pub fn open(uri: &str) -> NixideResult<Self> { pub fn open(uri: &str) -> NixideResult<Rc<RefCell<Self>>> {
Self::open_ptr(uri.as_c_ptr()?) Self::open_ptr(uri.as_c_ptr()?)
} }
/// Opens a connection to the default Nix store. /// Opens a connection to the default Nix store.
/// ///
pub fn default() -> NixideResult<Self> { pub fn default() -> NixideResult<Rc<RefCell<Self>>> {
Self::open_ptr(null()) Self::open_ptr(null())
} }
#[inline] #[inline]
fn open_ptr(uri_ptr: *const c_char) -> NixideResult<Self> { fn open_ptr(uri_ptr: *const c_char) -> NixideResult<Rc<RefCell<Self>>> {
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
// XXX: TODO: allow args to be parsed instead of just `null_mut` // XXX: TODO: allow args to be parsed instead of just `null_mut`
sys::nix_store_open(ctx.as_ptr(), uri_ptr, null_mut()) sys::nix_store_open(ctx.as_ptr(), uri_ptr, null_mut())
})?; })?;
Ok(Store { inner }) Ok(Rc::new(RefCell::new(Store { inner })))
} }
/// Realize a store path. /// Realize a store path.

View file

@ -1,10 +1,7 @@
use serial_test::serial; use serial_test::serial;
use super::{Store, StorePath}; use super::{Store, StorePath};
use crate::errors::ErrorContext;
use crate::init::LIBNIX_INIT_STATUS; use crate::init::LIBNIX_INIT_STATUS;
use crate::sys;
use crate::util::wrappers::AsInnerPtr as _;
#[test] #[test]
#[serial] #[serial]
@ -22,7 +19,7 @@ fn test_store_path_parse() {
let store = Store::default().expect("Failed to open store"); let store = Store::default().expect("Failed to open store");
// Try parsing a well-formed store path // Try parsing a well-formed store path
let result = StorePath::fake_path(&store); let result = StorePath::fake_path(&store.borrow());
result.expect("idk hopefully this fails"); result.expect("idk hopefully this fails");
} }
@ -34,7 +31,8 @@ fn test_store_path_clone() {
let store = Store::default().expect("Failed to open store"); let store = Store::default().expect("Failed to open store");
// Try to get a valid store path by parsing // Try to get a valid store path by parsing
let path = StorePath::fake_path(&store).expect("Failed to create `StorePath::fake_path`"); let path =
StorePath::fake_path(&store.borrow()).expect("Failed to create `StorePath::fake_path`");
let cloned = path.clone(); let cloned = path.clone();
// Assert that the cloned path has the same name as the original // Assert that the cloned path has the same name as the original