Compare commits
5 commits
bc56ecca6e
...
eb2a5d0ec2
| Author | SHA1 | Date | |
|---|---|---|---|
| eb2a5d0ec2 | |||
| f76658fcfb | |||
| 378569ff24 | |||
| 9f90e0c323 | |||
| 93d76c002e |
19 changed files with 520 additions and 322 deletions
|
|
@ -1,5 +1,6 @@
|
|||
use std::env;
|
||||
use std::fs;
|
||||
use std::iter;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use bindgen::RustEdition;
|
||||
|
|
@ -76,36 +77,41 @@ impl ParseCallbacks for BindfmtCallbacks {
|
|||
}
|
||||
}
|
||||
|
||||
const LIBS: &[&'static str] = &[
|
||||
const FEATURES: &[&'static str] = &[
|
||||
#[cfg(feature = "nix-util-c")]
|
||||
"nix-util-c",
|
||||
"util",
|
||||
#[cfg(feature = "nix-store-c")]
|
||||
"nix-store-c",
|
||||
"store",
|
||||
#[cfg(feature = "nix-expr-c")]
|
||||
"nix-expr-c",
|
||||
"expr",
|
||||
#[cfg(feature = "nix-fetchers-c")]
|
||||
"nix-fetchers-c",
|
||||
"fetchers",
|
||||
#[cfg(feature = "nix-flake-c")]
|
||||
"nix-flake-c",
|
||||
"flake",
|
||||
#[cfg(feature = "nix-main-c")]
|
||||
"nix-main-c",
|
||||
"main",
|
||||
];
|
||||
|
||||
fn main() {
|
||||
let libs: Vec<pkg_config::Library> = LIBS
|
||||
let libs: Vec<pkg_config::Library> = FEATURES
|
||||
.iter()
|
||||
.map(|&name| {
|
||||
.map(|&feature| {
|
||||
let name = &format!("nix-{feature}-c");
|
||||
pkg_config::probe_library(name).expect(&format!("Unable to find .pc file for {}", name))
|
||||
})
|
||||
.collect();
|
||||
|
||||
#[allow(unused)]
|
||||
let include_paths: Vec<PathBuf> = libs
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|lib| lib.include_paths)
|
||||
.flatten()
|
||||
.chain(iter::once(fs::canonicalize("./libnixide-c").unwrap()))
|
||||
.unique()
|
||||
.collect();
|
||||
|
||||
#[allow(unused)]
|
||||
let link_paths: Vec<PathBuf> = libs
|
||||
.clone()
|
||||
.into_iter()
|
||||
|
|
@ -114,20 +120,7 @@ fn main() {
|
|||
.unique()
|
||||
.collect();
|
||||
|
||||
// ::DEBUG:DEBUG::
|
||||
// for path in link_paths {
|
||||
// println!("cargo::rustc-link-lib={}", path.display());
|
||||
// }
|
||||
// ::DEBUG:DEBUG::
|
||||
|
||||
let clang_args: Vec<String> = vec!["-x", "c++", "-std=c++23"]
|
||||
.into_iter()
|
||||
.map(|s: &str| s.to_owned())
|
||||
.chain(include_paths.iter().map(|p| format!("-I{}", p.display())))
|
||||
.collect();
|
||||
|
||||
dbg!(&clang_args);
|
||||
|
||||
// build the libnixide-c extension
|
||||
cc::Build::new()
|
||||
// .cargo_output(true)
|
||||
// .cargo_warnings(true)
|
||||
|
|
@ -135,15 +128,19 @@ fn main() {
|
|||
// .cargo_debug(cfg!(debug_assertions))
|
||||
.cpp(true)
|
||||
.std("c++23") // libnix compiles against `-std=c++23`
|
||||
.cpp_link_stdlib("stdc++") // use libstdc++
|
||||
.flags(["-fconcepts-diagnostics-depth=2"])
|
||||
.file("libnixide-c/nixide_api_flake.cc")
|
||||
.file("libnixide-c/nixide_api_fetchers.cc")
|
||||
// .files(LIBS.iter().map(|s| (*s).strip_prefix("nix-").unwrap().strip_suffix("-c").unwrap()))
|
||||
.cpp_link_stdlib("c++") // libstdc++ for GNU, c++ for Clang
|
||||
.opt_level((!cfg!(debug_assertions)) as u32 * 3)
|
||||
.files(FEATURES.iter().map(|&feature| format!("libnixide-c/nixide_api_{feature}.cc")))
|
||||
.includes(&include_paths)
|
||||
.compile("nixide");
|
||||
.compile("nixide-c"); // libnixide-c
|
||||
|
||||
let clang_args: Vec<String> = vec!["-x", "c++", "-std=c++23"]
|
||||
.into_iter()
|
||||
.map(|s: &str| s.to_owned())
|
||||
.chain(include_paths.iter().map(|p| format!("-I{}", p.display())))
|
||||
.collect();
|
||||
dbg!(&clang_args);
|
||||
|
||||
let mut builder = bindgen::Builder::default()
|
||||
.rust_edition(RustEdition::Edition2024)
|
||||
.clang_args(clang_args)
|
||||
|
|
@ -156,8 +153,8 @@ fn main() {
|
|||
.rustfmt_configuration_file(std::fs::canonicalize("rustfmt.toml").ok())
|
||||
// Control allow/block listing
|
||||
.allowlist_recursively(true)
|
||||
// .allowlist_file(r".*nix_api_[a-z]+(_internal)?\.h")
|
||||
.allowlist_file(r".*nix_api_[a-z]+(/[a-z_]+)?\.h")
|
||||
.allowlist_file(r".*nixide_api_[a-z]+(/[a-z_]+)?\.h")
|
||||
|
||||
// .layout_tests(false) // DEBUG
|
||||
.use_core() // use ::core instead of ::std
|
||||
|
|
@ -181,10 +178,10 @@ fn main() {
|
|||
.raw_line("/** These bindings were auto-generated for the Nixide project (https://github.com/cry128/nixide) */");
|
||||
|
||||
// Register the input headers we would like to generate bindings for
|
||||
builder = LIBS
|
||||
builder = FEATURES
|
||||
.iter()
|
||||
.map(|lib| {
|
||||
let path = format!("include/{}.h", lib.strip_suffix("-c").unwrap());
|
||||
.map(|&feature| {
|
||||
let path = format!("include/nix-{feature}.h");
|
||||
assert!(fs::exists(&path).unwrap());
|
||||
// Invalidate the built crate if the binding headers change
|
||||
println!("cargo::rerun-if-changed={path}");
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
#define NIXIDE_EXPR
|
||||
|
||||
// Nix C API for the Nix expressions evaluator.
|
||||
//
|
||||
#include <nix_api_expr.h>
|
||||
// #include <nix_api_expr_internal.h>
|
||||
|
||||
// Nix C API for value manipulation.
|
||||
//
|
||||
|
|
@ -13,4 +13,8 @@
|
|||
//
|
||||
#include <nix_api_external.h>
|
||||
|
||||
// Nixide C API extensions for the Nix expressions evaluator.
|
||||
//
|
||||
#include <nixide_api_expr.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
#ifndef NIXIDE_FETCHERS
|
||||
#define NIXIDE_FETCHERS
|
||||
|
||||
// #include <nix_api_fetchers_internal.hh>
|
||||
|
||||
// Nix C API for fetcher operations.
|
||||
//
|
||||
#include <nix_api_fetchers.h>
|
||||
|
||||
// Nixide C API extensions for fetcher operations.
|
||||
//
|
||||
#include <nixide_api_fetchers.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
#ifndef NIXIDE_FLAKE
|
||||
#define NIXIDE_FLAKE
|
||||
|
||||
// #include <nix_api_flake_internal.hh>
|
||||
|
||||
// Nix C API for flake support.
|
||||
//
|
||||
#include <nix_api_flake.h>
|
||||
|
||||
// Nixide C API extensions for flake support.
|
||||
//
|
||||
#include <nixide_api_flake.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5,4 +5,8 @@
|
|||
//
|
||||
#include <nix_api_main.h>
|
||||
|
||||
// Nixide C API extensions for CLI support.
|
||||
//
|
||||
#include <nixide_api_main.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,9 +4,17 @@
|
|||
// Nix C API for store operations.
|
||||
//
|
||||
#include <nix_api_store.h>
|
||||
// #include <nix_api_store_internal.h>
|
||||
|
||||
// Nix C API for derivation operations that don't require a store.
|
||||
//
|
||||
#include <nix_api_store/derivation.h>
|
||||
|
||||
// Nix C API for store path operations that don't require a store.
|
||||
//
|
||||
#include <nix_api_store/store_path.h>
|
||||
|
||||
// Nixide C API extensions for store operations.
|
||||
//
|
||||
#include <nixide_api_store.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
// the Nix C APIs for error handling.
|
||||
//
|
||||
#include <nix_api_util.h>
|
||||
// #include <nix_api_util_internal.h>
|
||||
|
||||
// Nixide C API extensions for utilities.
|
||||
//
|
||||
#include <nixide_api_util.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
extern "C" {
|
||||
|
||||
nix_err nixide_register_plugin(nix_c_context * context, char * plugin)
|
||||
nix_err nix_register_plugin(nix_c_context * context, char * plugin)
|
||||
{
|
||||
if (context)
|
||||
context->last_err_code = NIX_OK;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
// NOTE: all plugins should be registered BEFORE `nix_init_plugins` is run
|
||||
nix_err nixide_register_plugin(nix_c_context * context, char * plugin);
|
||||
nix_err nix_register_plugin(nix_c_context * context, char * plugin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ impl<'a> RealisedString<'a> {
|
|||
path: Self::parse_path(inner.as_ptr(), state.store_ref().clone()),
|
||||
children: LazyArray::new(
|
||||
size,
|
||||
Box::new(|_| StorePath::fake_path(state.store_ref().clone()).unwrap()),
|
||||
Box::new(|_| StorePath::fake_path(state.store_ref().clone())),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ impl<'a> RealisedString<'a> {
|
|||
err
|
||||
)
|
||||
});
|
||||
StorePath::parse(store, &path_str).unwrap_or_else(|err| {
|
||||
StorePath::new(store, &path_str).unwrap_or_else(|err| {
|
||||
panic_issue_call_failed!(
|
||||
"`sys::nix_realised_string_get_buffer_(start|size)` invalid store path ({})",
|
||||
err
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::ffi::c_char;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use super::{FlakeRef, FlakeSettings};
|
||||
|
|
@ -77,6 +78,60 @@ impl FlakeLockFlags {
|
|||
Ok(FlakeLockFlags { inner })
|
||||
}
|
||||
|
||||
/// Adds an input override to the lock file that will be produced.
|
||||
/// The [LockedFlake::lock] operation will not write to the lock file.
|
||||
///
|
||||
/// # Warning
|
||||
///
|
||||
/// Calling this function will implicitly set the [FlakeLockMode] to
|
||||
/// [FlakeLockMode::Virtual] if `self.mode` is not [FlakeLockMode::Check].
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `path` - The input name/path to override (must not be empty)
|
||||
/// * `flakeref` - The flake reference to use as the override
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn override_input(self, input: &str, flakeref: &FlakeRef) -> NixideResult<Self> {
|
||||
// XXX: TODO: should `input` be wrapped as `format!("inputs.{input}")`?
|
||||
let input_path = input.as_c_ptr()?;
|
||||
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_add_input_override(
|
||||
ctx.as_ptr(),
|
||||
self.as_ptr(),
|
||||
input_path,
|
||||
flakeref.as_ptr(),
|
||||
);
|
||||
})?;
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Adds an input update to the lock file that will be produced.
|
||||
/// Meaning the current pinned version is ignored, and updated
|
||||
/// to the latest version the fetcher can resolve.
|
||||
///
|
||||
/// This is equivalent to running `nix flake update ${input}`.
|
||||
///
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn update_input(self, input: &str) -> NixideResult<Self> {
|
||||
// XXX: TODO: should `input` be wrapped as `format!("inputs.{input}")`?
|
||||
let input_path = input.as_c_ptr()?;
|
||||
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_add_input_update(ctx.as_ptr(), self.as_ptr(), input_path);
|
||||
})?;
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn set_mode(self, mode: FlakeLockMode) -> NixideResult<Self> {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| {
|
||||
match mode {
|
||||
|
|
@ -90,33 +145,176 @@ impl FlakeLockFlags {
|
|||
sys::nix_flake_lock_flags_set_mode_check(ctx.as_ptr(), self.as_ptr())
|
||||
},
|
||||
};
|
||||
});
|
||||
})?;
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Adds an input override to the lock file that will be produced.
|
||||
/// The [LockedFlake::lock] operation will not write to the lock file.
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// # Warning
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
/// Calling this function will implicitly set the [FlakeLockMode] to
|
||||
/// [FlakeLockMode::Virtual] if `self.mode` is not [FlakeLockMode::Check].
|
||||
#[allow(unused)]
|
||||
pub fn recreate_lock_file(self, value: bool) -> Self {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_set_recreate_lock_file(ctx.as_ptr(), self.as_ptr(), value)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// # Arguments
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
/// * `path` - The input name/path to override (must not be empty)
|
||||
/// * `flakeref` - The flake reference to use as the override
|
||||
pub fn override_input(&mut self, path: &str, flakeref: &FlakeRef) -> NixideResult<()> {
|
||||
let input_path = path.as_c_ptr()?;
|
||||
#[allow(unused)]
|
||||
pub fn update_lock_file(self, value: bool) -> Self {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_set_update_lock_file(ctx.as_ptr(), self.as_ptr(), value)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn write_lock_file(self, value: bool) -> Self {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_set_write_lock_file(ctx.as_ptr(), self.as_ptr(), value)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn commit_lock_file(self, value: bool) -> Self {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_set_commit_lock_file(ctx.as_ptr(), self.as_ptr(), value)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn allow_unlocked(self, value: bool) -> Self {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_set_allow_unlocked(ctx.as_ptr(), self.as_ptr(), value)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn fail_on_unlocked(self, value: bool) -> Self {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_set_fail_on_unlocked(ctx.as_ptr(), self.as_ptr(), value)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn use_registries(self, value: bool) -> Self {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_set_use_registries(ctx.as_ptr(), self.as_ptr(), value)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn apply_nix_config(self, value: bool) -> Self {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_set_apply_nix_config(ctx.as_ptr(), self.as_ptr(), value)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
/// Fails if the given `path` contains a NUL byte.
|
||||
///
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn input_lock_file_path(self, path: &str) -> NixideResult<Self> {
|
||||
let path_ptr = path.as_c_ptr()? as *mut c_char;
|
||||
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_add_input_override(
|
||||
sys::nix_flake_lock_flags_set_reference_lock_file_path(
|
||||
ctx.as_ptr(),
|
||||
self.as_ptr(),
|
||||
input_path,
|
||||
flakeref.as_ptr(),
|
||||
);
|
||||
path_ptr,
|
||||
)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
/// Fails if the given `path` contains a NUL byte.
|
||||
///
|
||||
/// # Nix C API Internals
|
||||
///
|
||||
/// This binding is **not provided by the Nix C API.**
|
||||
/// It is instead **exposed by the Nixide C API extensions.**
|
||||
///
|
||||
#[allow(unused)]
|
||||
pub fn output_lock_file_path(self, path: &str) -> NixideResult<Self> {
|
||||
let path_ptr = path.as_c_ptr()? as *mut c_char;
|
||||
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_lock_flags_set_output_lock_file_path(
|
||||
ctx.as_ptr(),
|
||||
self.as_ptr(),
|
||||
path_ptr,
|
||||
)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,104 +0,0 @@
|
|||
use std::ffi::{c_char, c_void};
|
||||
use std::ptr::{NonNull, null_mut};
|
||||
|
||||
use super::{FetchersSettings, FlakeRefParseFlags, FlakeSettings};
|
||||
use crate::NixideError;
|
||||
use crate::errors::{ErrorContext, new_nixide_error};
|
||||
use crate::sys;
|
||||
use crate::util::wrap;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
|
||||
pub struct FlakeRef {
|
||||
inner: NonNull<sys::NixFlakeReference>,
|
||||
fragment: String,
|
||||
|
||||
fetch_settings: FetchersSettings,
|
||||
flake_settings: FlakeSettings,
|
||||
}
|
||||
|
||||
// impl Clone for FlakeReference {
|
||||
// fn clone(&self) -> Self {
|
||||
// wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
// sys::nix_gc_incref(ctx.as_ptr(), self.as_ptr() as *mut c_void);
|
||||
// })
|
||||
// .unwrap();
|
||||
//
|
||||
// Self {
|
||||
// inner: self.inner.clone(),
|
||||
// fragment: self.fragment.clone(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl Drop for FlakeRef {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
sys::nix_flake_reference_free(self.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::NixFlakeReference> for FlakeRef {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::NixFlakeReference {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::NixFlakeReference {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::NixFlakeReference {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl FlakeRef {
|
||||
/// Parse a flake reference from a string.
|
||||
/// The string must be a valid flake reference, such as `github:owner/repo`.
|
||||
/// It may also be suffixed with a `#` and a fragment, such as `github:owner/repo#something`,
|
||||
/// in which case, the returned string will contain the fragment.
|
||||
pub fn parse<S: AsRef<str>>(reference: S) -> Result<FlakeRef, NixideError> {
|
||||
let fetch_settings = FetchersSettings::new()?;
|
||||
let flake_settings = FlakeSettings::new()?;
|
||||
let parse_flags = FlakeRefParseFlags::new(&flake_settings)?;
|
||||
|
||||
let mut ptr: *mut sys::NixFlakeReference = null_mut();
|
||||
let fragment = wrap::nix_string_callback!(
|
||||
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_reference_and_fragment_from_string(
|
||||
ctx.as_ptr(),
|
||||
fetch_settings.as_ptr(),
|
||||
flake_settings.as_ptr(),
|
||||
parse_flags.as_ptr(),
|
||||
reference.as_ref().as_ptr() as *const c_char,
|
||||
reference.as_ref().len(),
|
||||
&mut ptr,
|
||||
Some(callback),
|
||||
userdata as *mut c_void,
|
||||
)
|
||||
}
|
||||
)?;
|
||||
|
||||
match NonNull::new(ptr) {
|
||||
Some(inner) => Ok(FlakeRef {
|
||||
inner,
|
||||
fragment,
|
||||
fetch_settings,
|
||||
flake_settings,
|
||||
}),
|
||||
None => Err(new_nixide_error!(NullPtr)),
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: TODO: is it possible to get the URI string itself? (minus the fragment part?)
|
||||
/// Get a shared reference to the URI fragment part.
|
||||
///
|
||||
#[inline]
|
||||
#[allow(unused)]
|
||||
pub fn fragment(&self) -> &str {
|
||||
&self.fragment
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,104 @@
|
|||
pub struct FlakeRef {}
|
||||
use std::ffi::{c_char, c_void};
|
||||
use std::ptr::{NonNull, null_mut};
|
||||
|
||||
impl FlakeRef {}
|
||||
use super::{FetchersSettings, FlakeRefParseFlags, FlakeSettings};
|
||||
use crate::NixideError;
|
||||
use crate::errors::{ErrorContext, new_nixide_error};
|
||||
use crate::sys;
|
||||
use crate::util::wrap;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
|
||||
pub struct FlakeRef {
|
||||
inner: NonNull<sys::NixFlakeReference>,
|
||||
fragment: String,
|
||||
|
||||
fetch_settings: FetchersSettings,
|
||||
flake_settings: FlakeSettings,
|
||||
}
|
||||
|
||||
// impl Clone for FlakeReference {
|
||||
// fn clone(&self) -> Self {
|
||||
// wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
// sys::nix_gc_incref(ctx.as_ptr(), self.as_ptr() as *mut c_void);
|
||||
// })
|
||||
// .unwrap();
|
||||
//
|
||||
// Self {
|
||||
// inner: self.inner.clone(),
|
||||
// fragment: self.fragment.clone(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl Drop for FlakeRef {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
sys::nix_flake_reference_free(self.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::NixFlakeReference> for FlakeRef {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::NixFlakeReference {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::NixFlakeReference {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::NixFlakeReference {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl FlakeRef {
|
||||
/// Parse a flake reference from a string.
|
||||
/// The string must be a valid flake reference, such as `github:owner/repo`.
|
||||
/// It may also be suffixed with a `#` and a fragment, such as `github:owner/repo#something`,
|
||||
/// in which case, the returned string will contain the fragment.
|
||||
pub fn parse<S: AsRef<str>>(reference: S) -> Result<FlakeRef, NixideError> {
|
||||
let fetch_settings = FetchersSettings::new()?;
|
||||
let flake_settings = FlakeSettings::new()?;
|
||||
let parse_flags = FlakeRefParseFlags::new(&flake_settings)?;
|
||||
|
||||
let mut ptr: *mut sys::NixFlakeReference = null_mut();
|
||||
let fragment = wrap::nix_string_callback!(
|
||||
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||
sys::nix_flake_reference_and_fragment_from_string(
|
||||
ctx.as_ptr(),
|
||||
fetch_settings.as_ptr(),
|
||||
flake_settings.as_ptr(),
|
||||
parse_flags.as_ptr(),
|
||||
reference.as_ref().as_ptr() as *const c_char,
|
||||
reference.as_ref().len(),
|
||||
&mut ptr,
|
||||
Some(callback),
|
||||
userdata as *mut c_void,
|
||||
)
|
||||
}
|
||||
)?;
|
||||
|
||||
match NonNull::new(ptr) {
|
||||
Some(inner) => Ok(FlakeRef {
|
||||
inner,
|
||||
fragment,
|
||||
fetch_settings,
|
||||
flake_settings,
|
||||
}),
|
||||
None => Err(new_nixide_error!(NullPtr)),
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: TODO: is it possible to get the URI string itself? (minus the fragment part?)
|
||||
/// Get a shared reference to the URI fragment part.
|
||||
///
|
||||
#[inline]
|
||||
#[allow(unused)]
|
||||
pub fn fragment(&self) -> &str {
|
||||
&self.fragment
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
mod fetchers_settings;
|
||||
mod flake_lock_flags;
|
||||
mod flake_reference;
|
||||
mod flake_reference_parse_flags;
|
||||
mod flake_settings;
|
||||
mod flakeref;
|
||||
mod flakeref_parse_flags;
|
||||
mod locked_flake;
|
||||
|
||||
use fetchers_settings::FetchersSettings;
|
||||
use flake_lock_flags::{FlakeLockFlags, FlakeLockMode};
|
||||
use flake_reference::FlakeRef;
|
||||
use flake_reference_parse_flags::FlakeRefParseFlags;
|
||||
pub use flake_settings::FlakeSettings;
|
||||
use flakeref::FlakeRef;
|
||||
use flakeref_parse_flags::FlakeRefParseFlags;
|
||||
pub use locked_flake::LockedFlake;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::NixideResult;
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::stdext::AsCPtr as _;
|
||||
use crate::util::wrap;
|
||||
use crate::util::wrappers::AsInnerPtr as _;
|
||||
|
||||
|
|
@ -8,3 +9,10 @@ pub fn load_plugins() -> NixideResult<()> {
|
|||
sys::nix_init_plugins(ctx.as_ptr());
|
||||
})
|
||||
}
|
||||
|
||||
pub fn register_plugin<S: AsRef<str>>(path: S) -> NixideResult<()> {
|
||||
let path_ptr = path.as_ref().into_c_ptr()?;
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_register_plugin(ctx.as_ptr(), path_ptr);
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ use std::rc::Rc;
|
|||
|
||||
use crate::NixideResult;
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::stdext::{AsCPtr as _, CCharPtrExt as _};
|
||||
use crate::stdext::AsCPtr as _;
|
||||
use crate::sys;
|
||||
use crate::util::wrap;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
use crate::util::{panic_issue_call_failed, wrap};
|
||||
|
||||
/// Nix store for managing packages and derivations.
|
||||
///
|
||||
|
|
@ -28,19 +28,6 @@ pub struct Store {
|
|||
inner: NonNull<sys::Store>,
|
||||
}
|
||||
|
||||
// impl Clone for Store {
|
||||
// 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::Store> for Store {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::Store {
|
||||
|
|
@ -71,17 +58,17 @@ impl Store {
|
|||
/// Returns an error if the store cannot be opened.
|
||||
///
|
||||
pub fn open(uri: &str) -> NixideResult<Rc<RefCell<Self>>> {
|
||||
Self::open_ptr(uri.as_c_ptr()?)
|
||||
unsafe { Self::open_ptr(uri.as_c_ptr()?) }
|
||||
}
|
||||
|
||||
/// Opens a connection to the default Nix store.
|
||||
///
|
||||
pub fn default() -> NixideResult<Rc<RefCell<Self>>> {
|
||||
Self::open_ptr(null())
|
||||
unsafe { Self::open_ptr(null()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn open_ptr(uri_ptr: *const c_char) -> NixideResult<Rc<RefCell<Self>>> {
|
||||
unsafe fn open_ptr(uri_ptr: *const c_char) -> NixideResult<Rc<RefCell<Self>>> {
|
||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||
// XXX: TODO: allow args to be parsed instead of just `null_mut`
|
||||
sys::nix_store_open(ctx.as_ptr(), uri_ptr, null_mut())
|
||||
|
|
@ -90,97 +77,6 @@ impl Store {
|
|||
Ok(Rc::new(RefCell::new(Store { inner })))
|
||||
}
|
||||
|
||||
/// Realize a store path.
|
||||
///
|
||||
/// This builds/downloads the store path and all its dependencies,
|
||||
/// making them available in the local store.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `path` - The store path to realize
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A vector of (output_name, store_path) tuples for each realized output.
|
||||
/// For example, a derivation might produce outputs like ("out", path1), ("dev", path2).
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the path cannot be realized.
|
||||
///
|
||||
pub fn realise(
|
||||
&self,
|
||||
path: &StorePath,
|
||||
user_callback: fn(&str, &StorePath),
|
||||
) -> NixideResult<Vec<(String, StorePath)>> {
|
||||
wrap::nix_callback!(
|
||||
|; userdata: fn(&str, &StorePath);
|
||||
output_name_ptr: *const c_char,
|
||||
output_path_ptr: *const sys::StorePath|
|
||||
-> Vec<(String, StorePath)> {
|
||||
// XXX: TODO: test to see if this is ever null ("out" as a default feels unsafe...)
|
||||
// NOTE: this also ensures `output_name_ptr` isn't null
|
||||
let output_name = output_name_ptr.to_utf8_string().unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
|
||||
|
||||
let inner = wrap::nix_ptr_fn!(|ctx| unsafe {
|
||||
sys::nix_store_path_clone(output_path_ptr as *mut sys::StorePath)
|
||||
}).unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
|
||||
let store_path = StorePath { inner };
|
||||
|
||||
let callback = unsafe { (*userdata).inner };
|
||||
callback(output_name.as_ref(), &store_path);
|
||||
|
||||
(unsafe {(*userdata).retval }).append((output_name, store_path));
|
||||
},
|
||||
|callback,
|
||||
state: *mut __UserData,
|
||||
ctx: &ErrorContext| unsafe {
|
||||
// register userdata
|
||||
// WARNING: Using `write` instead of assignment via `=`
|
||||
// WARNING: to not call `drop` on the old, uninitialized value.
|
||||
(&raw mut (*state).inner).write(user_callback);
|
||||
// register return value
|
||||
(&raw mut (*state).retval).write(Vec::new());
|
||||
|
||||
sys::nix_store_realise(
|
||||
ctx.as_ptr(),
|
||||
self.as_ptr(),
|
||||
path.as_ptr(),
|
||||
(*state).inner_ptr() as *mut c_void,
|
||||
Some(callback),
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Parse a store path string into a StorePath.
|
||||
///
|
||||
/// This is a convenience method that wraps `StorePath::parse()`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `path` - The store path string (e.g., "/nix/store/...")
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the path cannot be parsed.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use std::sync::Arc;
|
||||
/// # use nixide::Store;
|
||||
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// let store = Store::open(None)?;
|
||||
/// let path = store.store_path("/nix/store/...")?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
pub fn store_path(&self, path: &str) -> NixideResult<StorePath> {
|
||||
StorePath::parse(self, path)
|
||||
}
|
||||
|
||||
/// Get the version of a Nix store
|
||||
///
|
||||
/// If the store doesn't have a version (like the dummy store), returns None
|
||||
|
|
@ -198,7 +94,7 @@ impl Store {
|
|||
)
|
||||
}
|
||||
|
||||
/// Get the URI of a Nix store
|
||||
/// Get the URI of a Nix store as a String.
|
||||
///
|
||||
pub fn uri(&self) -> NixideResult<String> {
|
||||
wrap::nix_string_callback!(
|
||||
|
|
@ -213,6 +109,8 @@ impl Store {
|
|||
)
|
||||
}
|
||||
|
||||
/// Get the store directory path of a Nix store.
|
||||
///
|
||||
pub fn store_dir(&self) -> NixideResult<PathBuf> {
|
||||
wrap::nix_pathbuf_callback!(
|
||||
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||
|
|
@ -225,28 +123,6 @@ impl Store {
|
|||
}
|
||||
)
|
||||
}
|
||||
|
||||
pub fn copy_closure_to(&self, dst_store: &Store, store_path: &StorePath) -> NixideResult<()> {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_store_copy_closure(
|
||||
ctx.as_ptr(),
|
||||
self.as_ptr(),
|
||||
dst_store.as_ptr(),
|
||||
store_path.as_ptr(),
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
pub fn copy_closure_from(&self, src_store: &Store, store_path: &StorePath) -> NixideResult<()> {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_store_copy_closure(
|
||||
ctx.as_ptr(),
|
||||
src_store.as_ptr(),
|
||||
self.as_ptr(),
|
||||
store_path.as_ptr(),
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Store {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use std::cell::RefCell;
|
||||
use std::ffi::{CString, c_void};
|
||||
use std::ffi::{CString, c_char, c_void};
|
||||
use std::path::PathBuf;
|
||||
use std::ptr::NonNull;
|
||||
use std::rc::Rc;
|
||||
|
|
@ -7,6 +7,7 @@ use std::rc::Rc;
|
|||
use super::Store;
|
||||
use crate::NixideResult;
|
||||
use crate::errors::{ErrorContext, new_nixide_error};
|
||||
use crate::stdext::CCharPtrExt as _;
|
||||
use crate::sys;
|
||||
use crate::util::panic_issue_call_failed;
|
||||
use crate::util::wrap;
|
||||
|
|
@ -18,7 +19,7 @@ use crate::util::wrappers::AsInnerPtr;
|
|||
///
|
||||
pub struct StorePath {
|
||||
inner: NonNull<sys::StorePath>,
|
||||
store: Rc<RefCell<Store>>,
|
||||
store_ref: Rc<RefCell<Store>>,
|
||||
}
|
||||
|
||||
impl Clone for StorePath {
|
||||
|
|
@ -30,7 +31,7 @@ impl Clone for StorePath {
|
|||
|
||||
StorePath {
|
||||
inner,
|
||||
store: self.store.clone(),
|
||||
store_ref: self.store_ref.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -71,18 +72,33 @@ impl StorePath {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the path cannot be parsed.
|
||||
pub fn parse(store: Rc<RefCell<Store>>, path: &str) -> NixideResult<Self> {
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// use nixide::{Store, StorePath};
|
||||
///
|
||||
/// fn main() {
|
||||
/// let store_ref = Store::default().unwrap();
|
||||
/// let path = StorePath::new("/nix/store/f7gmvzd74wc1vlxzjdqy0af2381g8wr6-nix-manual-2.31.2-man").unwrap();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
pub fn new(store: Rc<RefCell<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 {
|
||||
sys::nix_store_parse_path(ctx.as_ptr(), store.borrow().as_ptr(), c_path.as_ptr())
|
||||
})?;
|
||||
|
||||
Ok(Self { inner, store })
|
||||
Ok(Self {
|
||||
inner,
|
||||
store_ref: store,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fake_path(store: Rc<RefCell<Store>>) -> NixideResult<Self> {
|
||||
Self::parse(store, "/nix/store/00000000000000000000000000000000-fake")
|
||||
pub fn fake_path(store: Rc<RefCell<Store>>) -> Self {
|
||||
Self::new(store, "/nix/store/00000000000000000000000000000000-fake").unwrap()
|
||||
}
|
||||
|
||||
/// Get the name component of the store path.
|
||||
|
|
@ -125,7 +141,7 @@ impl StorePath {
|
|||
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||
sys::nix_store_real_path(
|
||||
ctx.as_ptr(),
|
||||
self.store.borrow().as_ptr(),
|
||||
self.store_ref.borrow().as_ptr(),
|
||||
self.as_ptr(),
|
||||
Some(callback),
|
||||
userdata as *mut c_void,
|
||||
|
|
@ -176,11 +192,11 @@ impl StorePath {
|
|||
store_path: *const sys::StorePath,
|
||||
| -> () {
|
||||
let callback: fn(&StorePath) = unsafe { (*userdata).inner.1 };
|
||||
let store = unsafe { (*userdata).inner.0.clone() };
|
||||
let store_ref = unsafe { (*userdata).inner.0.clone() };
|
||||
|
||||
let path = &StorePath {
|
||||
inner: NonNull::new(unsafe { store.borrow().as_ptr() } as *mut sys::StorePath).unwrap(),
|
||||
store,
|
||||
inner: NonNull::new(unsafe { store_ref.borrow().as_ptr() } as *mut sys::StorePath).unwrap(),
|
||||
store_ref,
|
||||
};
|
||||
|
||||
callback(&path);
|
||||
|
|
@ -191,11 +207,11 @@ impl StorePath {
|
|||
// register userdata
|
||||
// WARNING: Using `write` instead of assignment via `=`
|
||||
// WARNING: to not call `drop` on the old, uninitialized value.
|
||||
(&raw mut (*state).inner).write((self.store.clone(), user_callback));
|
||||
(&raw mut (*state).inner).write((self.store_ref.clone(), user_callback));
|
||||
|
||||
sys::nix_store_get_fs_closure(
|
||||
ctx.as_ptr(),
|
||||
self.store.borrow().as_ptr(),
|
||||
self.store_ref.borrow().as_ptr(),
|
||||
self.as_ptr(),
|
||||
flip,
|
||||
include_outputs,
|
||||
|
|
@ -206,7 +222,92 @@ impl StorePath {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn copy_closure_to(&self, dst_store_ref: Rc<RefCell<Store>>) -> NixideResult<()> {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_store_copy_closure(
|
||||
ctx.as_ptr(),
|
||||
self.store_ref.borrow().as_ptr(),
|
||||
dst_store_ref.borrow().as_ptr(),
|
||||
self.as_ptr(),
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
pub fn copy_closure_from(&self, src_store_ref: Rc<RefCell<Store>>) -> NixideResult<()> {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_store_copy_closure(
|
||||
ctx.as_ptr(),
|
||||
src_store_ref.borrow().as_ptr(),
|
||||
self.store_ref.borrow().as_ptr(),
|
||||
self.as_ptr(),
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
/// Realize a store path.
|
||||
///
|
||||
/// This builds/downloads the store path and all its dependencies,
|
||||
/// making them available in the local store.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `path` - The store path to realize
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A vector of (output_name, store_path) tuples for each realized output.
|
||||
/// For example, a derivation might produce outputs like ("out", path1), ("dev", path2).
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the path cannot be realized.
|
||||
///
|
||||
pub fn realise(
|
||||
&self,
|
||||
user_callback: fn(&str, &StorePath),
|
||||
) -> NixideResult<Vec<(String, StorePath)>> {
|
||||
wrap::nix_callback!(
|
||||
|; userdata: (Rc<RefCell<Store>>, fn(&str, &StorePath));
|
||||
output_name_ptr: *const c_char,
|
||||
output_path_ptr: *const sys::StorePath|
|
||||
-> Vec<(String, StorePath)> {
|
||||
// XXX: TODO: test to see if this is ever null ("out" as a default feels unsafe...)
|
||||
// NOTE: this also ensures `output_name_ptr` isn't null
|
||||
let output_name = output_name_ptr.to_utf8_string().unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
|
||||
|
||||
let inner = wrap::nix_ptr_fn!(|ctx| unsafe {
|
||||
sys::nix_store_path_clone(output_path_ptr as *mut sys::StorePath)
|
||||
}).unwrap_or_else(|err| panic_issue_call_failed!("{}", err));
|
||||
|
||||
let store_ref = unsafe { (*userdata).inner.0.clone() };
|
||||
let callback = unsafe { (*userdata).inner.1 };
|
||||
|
||||
let store_path = StorePath { inner, store_ref };
|
||||
|
||||
callback(output_name.as_ref(), &store_path);
|
||||
|
||||
unsafe { (*userdata).retval.push((output_name, store_path)) };
|
||||
},
|
||||
|callback,
|
||||
state: *mut __UserData,
|
||||
ctx: &ErrorContext| unsafe {
|
||||
// register userdata
|
||||
// WARNING: Using `write` instead of assignment via `=`
|
||||
// WARNING: to not call `drop` on the old, uninitialized value.
|
||||
(&raw mut (*state).inner).write((self.store_ref.clone(), user_callback));
|
||||
// register return value
|
||||
(&raw mut (*state).retval).write(Vec::new());
|
||||
|
||||
sys::nix_store_realise(
|
||||
ctx.as_ptr(),
|
||||
self.store_ref.borrow().as_ptr(),
|
||||
self.as_ptr(),
|
||||
(*state).inner_ptr() as *mut c_void,
|
||||
Some(callback),
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// XXX: TODO: nix 2.34.4 adds a LOT here (ie especially around derivations)
|
||||
// XXX: TODO: it also removes nix_store_path* functions (ie nix_store_path_free)?
|
||||
// XXX: TODO: why?? try and research this, maybe they didn't mean to??
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,10 @@ fn test_store_opening() {
|
|||
fn test_store_path_parse() {
|
||||
assert!(unsafe { matches!(LIBNIX_INIT_STATUS, Some(Ok(_))) });
|
||||
|
||||
let store = Store::default().expect("Failed to open store");
|
||||
let store_ref = Store::default().expect("Failed to open store");
|
||||
|
||||
// Try parsing a well-formed store path
|
||||
let result = StorePath::fake_path(&store.borrow());
|
||||
result.expect("idk hopefully this fails");
|
||||
StorePath::fake_path(store_ref.clone());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -28,11 +27,10 @@ fn test_store_path_parse() {
|
|||
fn test_store_path_clone() {
|
||||
assert!(unsafe { matches!(LIBNIX_INIT_STATUS, Some(Ok(_))) });
|
||||
|
||||
let store = Store::default().expect("Failed to open store");
|
||||
let store_ref = Store::default().expect("Failed to open store");
|
||||
|
||||
// Try to get a valid store path by parsing
|
||||
let path =
|
||||
StorePath::fake_path(&store.borrow()).expect("Failed to create `StorePath::fake_path`");
|
||||
let path = StorePath::fake_path(store_ref.clone());
|
||||
let cloned = path.clone();
|
||||
|
||||
// Assert that the cloned path has the same name as the original
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue