Compare commits
No commits in common. "cb2ac77f1edd7ecf4dac1d5de680d0674452bb37" and "f6de1d7b208d5b5396265e87c8bfce2c68c2b0f0" have entirely different histories.
cb2ac77f1e
...
f6de1d7b20
25 changed files with 604 additions and 596 deletions
18
flake.lock
generated
18
flake.lock
generated
|
|
@ -8,11 +8,11 @@
|
||||||
"rust-analyzer-src": "rust-analyzer-src"
|
"rust-analyzer-src": "rust-analyzer-src"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1776025235,
|
"lastModified": 1774682177,
|
||||||
"narHash": "sha256-zZIrW6G6GiFkpfFrOVjxYAVcXoKBMHv06kaUTOiqOq0=",
|
"narHash": "sha256-OVbuJnJLlbHE28eRMudjtA6NXz/ifuXSho79gvh6GHY=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "fenix",
|
"repo": "fenix",
|
||||||
"rev": "dfe3f197bf8f3e95d705b7323b46e3a087c88972",
|
"rev": "e0f515387df77b9fdbaaf81e7f866f0365474c18",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -23,11 +23,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775710090,
|
"lastModified": 1775036866,
|
||||||
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
|
"narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
|
"rev": "6201e203d09599479a3b3450ed24fa81537ebc4e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -47,11 +47,11 @@
|
||||||
"rust-analyzer-src": {
|
"rust-analyzer-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775939146,
|
"lastModified": 1774569884,
|
||||||
"narHash": "sha256-YI8Hkuc2PSEJNwC8Qj3/DlMt1JfRv0MqzrnH/Mh9i5s=",
|
"narHash": "sha256-E8iWEPzg7OnE0XXXjo75CX7xFauqzJuGZ5wSO9KS8Ek=",
|
||||||
"owner": "rust-lang",
|
"owner": "rust-lang",
|
||||||
"repo": "rust-analyzer",
|
"repo": "rust-analyzer",
|
||||||
"rev": "09dc7aca674f53032f9d819f6fea01046e3d473f",
|
"rev": "443ddcddd0c73b07b799d052f5ef3b448c2f3508",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
127
flake.nix
127
flake.nix
|
|
@ -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:
|
||||||
|
|
@ -35,6 +36,9 @@
|
||||||
});
|
});
|
||||||
in {
|
in {
|
||||||
overlays = {
|
overlays = {
|
||||||
|
default = self: super: {
|
||||||
|
libclang = super.llvmPackages_21.libclang;
|
||||||
|
};
|
||||||
fenix = inputs.fenix.overlays.default;
|
fenix = inputs.fenix.overlays.default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -43,11 +47,12 @@
|
||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: {
|
||||||
|
default = let
|
||||||
nixForBindings = pkgs.nixVersions.nix_2_34;
|
nixForBindings = pkgs.nixVersions.nix_2_34;
|
||||||
inherit (pkgs.rustc) llvmPackages;
|
inherit (pkgs.rustc) llvmPackages;
|
||||||
in {
|
in
|
||||||
default = pkgs.mkShell rec {
|
pkgs.mkShell rec {
|
||||||
name = "nixide";
|
name = "nixide";
|
||||||
shell = "${pkgs.bash}/bin/bash";
|
shell = "${pkgs.bash}/bin/bash";
|
||||||
strictDeps = true;
|
strictDeps = true;
|
||||||
|
|
@ -64,8 +69,8 @@
|
||||||
cargo-llvm-cov
|
cargo-llvm-cov
|
||||||
cargo-nextest
|
cargo-nextest
|
||||||
|
|
||||||
clang
|
clang # DEBUG
|
||||||
clang-tools
|
clang-tools # DEBUG
|
||||||
|
|
||||||
libcxx
|
libcxx
|
||||||
|
|
||||||
|
|
@ -85,84 +90,86 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
# packages we link against
|
# packages we link against
|
||||||
buildInputs = [
|
buildInputs = with pkgs; [
|
||||||
# pkgs.stdenv.cc
|
stdenv.cc
|
||||||
|
|
||||||
nixForBindings
|
nixForBindings
|
||||||
];
|
];
|
||||||
|
|
||||||
env = {
|
env = let
|
||||||
|
inherit (llvmPackages) llvm libclang;
|
||||||
|
in {
|
||||||
LD_LIBRARY_PATH = builtins.toString (lib.makeLibraryPath buildInputs);
|
LD_LIBRARY_PATH = builtins.toString (lib.makeLibraryPath buildInputs);
|
||||||
LIBCLANG_PATH = "${llvmPackages.libclang.lib}/lib";
|
LIBCLANG_PATH = "${libclang.lib}/lib";
|
||||||
|
|
||||||
RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}";
|
RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}";
|
||||||
BINDGEN_EXTRA_CLANG_ARGS = "--sysroot=${pkgs.glibc.dev}";
|
BINDGEN_EXTRA_CLANG_ARGS = "--sysroot=${pkgs.glibc.dev}";
|
||||||
|
|
||||||
# `cargo-llvm-cov` reads these environment variables to find these binaries,
|
# `cargo-llvm-cov` reads these environment variables to find these binaries,
|
||||||
# which are needed to run the tests
|
# which are needed to run the tests
|
||||||
LLVM_COV = "${llvmPackages.llvm}/bin/llvm-cov";
|
LLVM_COV = "${llvm}/bin/llvm-cov";
|
||||||
LLVM_PROFDATA = "${llvmPackages.llvm}/bin/llvm-profdata";
|
LLVM_PROFDATA = "${llvm}/bin/llvm-profdata";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# nightly = let
|
nightly = let
|
||||||
# nixForBindings = pkgs.nixVersions.nix_2_34;
|
nixForBindings = pkgs.nixVersions.nix_2_34;
|
||||||
# inherit (pkgs.rustc) llvmPackages;
|
inherit (pkgs.rustc) llvmPackages;
|
||||||
# in
|
in
|
||||||
# pkgs.mkShell rec {
|
pkgs.mkShell rec {
|
||||||
# name = "nixide";
|
name = "nixide";
|
||||||
# shell = "${pkgs.bash}/bin/bash";
|
shell = "${pkgs.bash}/bin/bash";
|
||||||
# strictDeps = true;
|
strictDeps = true;
|
||||||
|
|
||||||
# # packages we need at runtime
|
# packages we need at runtime
|
||||||
# packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
# llvmPackages.lld
|
llvmPackages.lld
|
||||||
# lldb
|
lldb
|
||||||
# (pkgs.fenix.complete.withComponents [
|
(pkgs.fenix.complete.withComponents [
|
||||||
# "cargo"
|
"cargo"
|
||||||
# "clippy"
|
"clippy"
|
||||||
# "rust-src"
|
"rust-src"
|
||||||
# "rustc"
|
"rustc"
|
||||||
# "rustfmt"
|
"rustfmt"
|
||||||
# ])
|
])
|
||||||
# rust-analyzer-nightly
|
rust-analyzer-nightly
|
||||||
|
|
||||||
# # cargo-c
|
# cargo-c
|
||||||
# # cargo-llvm-cov
|
# cargo-llvm-cov
|
||||||
# # cargo-nextest
|
# cargo-nextest
|
||||||
# ];
|
];
|
||||||
|
|
||||||
# # packages we need at build time
|
# packages we need at build time
|
||||||
# nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
# pkg-config
|
pkg-config
|
||||||
# glibc.dev
|
glibc.dev
|
||||||
# nixForBindings.dev
|
nixForBindings.dev
|
||||||
|
|
||||||
# rustPlatform.bindgenHook
|
rustPlatform.bindgenHook
|
||||||
# ];
|
];
|
||||||
|
|
||||||
# # packages we link against
|
# packages we link against
|
||||||
# buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
# stdenv.cc
|
stdenv.cc
|
||||||
|
|
||||||
# nixForBindings
|
nixForBindings
|
||||||
# ];
|
];
|
||||||
|
|
||||||
# env = let
|
env = let
|
||||||
# inherit (llvmPackages) llvm libclang;
|
inherit (llvmPackages) llvm libclang;
|
||||||
# in {
|
in {
|
||||||
# LD_LIBRARY_PATH = builtins.toString (lib.makeLibraryPath buildInputs);
|
LD_LIBRARY_PATH = builtins.toString (lib.makeLibraryPath buildInputs);
|
||||||
# LIBCLANG_PATH = "${libclang.lib}/lib";
|
LIBCLANG_PATH = "${libclang.lib}/lib";
|
||||||
|
|
||||||
# RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}";
|
RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}";
|
||||||
# BINDGEN_EXTRA_CLANG_ARGS = "--sysroot=${pkgs.glibc.dev}";
|
BINDGEN_EXTRA_CLANG_ARGS = "--sysroot=${pkgs.glibc.dev}";
|
||||||
|
|
||||||
# # `cargo-llvm-cov` reads these environment variables to find these binaries,
|
# `cargo-llvm-cov` reads these environment variables to find these binaries,
|
||||||
# # which are needed to run the tests
|
# which are needed to run the tests
|
||||||
# LLVM_COV = "${llvm}/bin/llvm-cov";
|
LLVM_COV = "${llvm}/bin/llvm-cov";
|
||||||
# LLVM_PROFDATA = "${llvm}/bin/llvm-profdata";
|
LLVM_PROFDATA = "${llvm}/bin/llvm-profdata";
|
||||||
# };
|
};
|
||||||
# };
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ fn main() {
|
||||||
// .cargo_debug(cfg!(debug_assertions))
|
// .cargo_debug(cfg!(debug_assertions))
|
||||||
.cpp(true)
|
.cpp(true)
|
||||||
.std("c++23") // libnix compiles against `-std=c++23`
|
.std("c++23") // libnix compiles against `-std=c++23`
|
||||||
|
.cpp_link_stdlib("c++") // libstdc++ for GNU, c++ for Clang
|
||||||
.opt_level((!cfg!(debug_assertions)) as u32 * 3)
|
.opt_level((!cfg!(debug_assertions)) as u32 * 3)
|
||||||
.files(FEATURES.iter().map(|&feature| format!("libnixide-c/nixide_api_{feature}.cc")))
|
.files(FEATURES.iter().map(|&feature| format!("libnixide-c/nixide_api_{feature}.cc")))
|
||||||
.includes(&include_paths)
|
.includes(&include_paths)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ nix_err nix_register_plugin(nix_c_context * context, char * plugin)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
if (plugin == nullptr) {
|
if (plugin == nullptr) {
|
||||||
// TODO: should this be `NIX_ERR_RECOVERABLE` or `NIX_ERR_UNKNOWN`?
|
// TODO: should this be `NIX_ERR_RECOVERABLE` or `NIX_ERR_UNKNOWN`?
|
||||||
return nix_set_err_msg(context, NIX_ERR_UNKNOWN, "Plugin is null");
|
return nix_set_err_msg(context, NIX_ERR_RECOVERABLE, "Plugin is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
void * handle = dlopen("libnixmainc.so", RTLD_LAZY | RTLD_GLOBAL);
|
void * handle = dlopen("libnixmainc.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,14 @@
|
||||||
// static std::optional<std::string> programName;
|
// static std::optional<std::string> programName;
|
||||||
// };
|
// };
|
||||||
|
|
||||||
use std::ffi::CString;
|
|
||||||
use std::ffi::c_uint;
|
use std::ffi::c_uint;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use super::{NixError, NixideResult};
|
use super::{NixError, NixideResult};
|
||||||
use crate::errors::ToNixideResult as _;
|
use crate::stdext::{AsCPtr as _, CCharPtrExt as _};
|
||||||
use crate::stdext::CCharPtrExt as _;
|
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
@ -101,7 +100,7 @@ impl Into<NixideResult<()>> for &ErrorContext {
|
||||||
};
|
};
|
||||||
let msg = match self.get_msg() {
|
let msg = match self.get_msg() {
|
||||||
Some(msg) => msg,
|
Some(msg) => msg,
|
||||||
None => String::new(),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let err = match inner {
|
let err = match inner {
|
||||||
|
|
@ -110,8 +109,13 @@ impl Into<NixideResult<()>> for &ErrorContext {
|
||||||
sys::NixErr::Overflow => NixError::Overflow,
|
sys::NixErr::Overflow => NixError::Overflow,
|
||||||
sys::NixErr::Key => NixError::KeyNotFound(None),
|
sys::NixErr::Key => NixError::KeyNotFound(None),
|
||||||
sys::NixErr::NixError => NixError::ExprEval {
|
sys::NixErr::NixError => NixError::ExprEval {
|
||||||
name: self.get_nix_err_name().unwrap(),
|
name: self
|
||||||
info_msg: self.get_nix_err_info_msg().unwrap_or_else(|| String::new()),
|
.get_nix_err_name()
|
||||||
|
.unwrap_or_else(|| panic_issue_call_failed!()),
|
||||||
|
|
||||||
|
info_msg: self
|
||||||
|
.get_nix_err_info_msg()
|
||||||
|
.unwrap_or_else(|| panic_issue_call_failed!()),
|
||||||
},
|
},
|
||||||
|
|
||||||
// XXX: WARNING: Recoverable only exists in later version of Nix
|
// XXX: WARNING: Recoverable only exists in later version of Nix
|
||||||
|
|
@ -190,11 +194,11 @@ impl ErrorContext {
|
||||||
///
|
///
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn set_err(&self, err: NixError, msg: &str) -> NixideResult<()> {
|
pub fn set_err(&self, err: NixError, msg: &str) -> NixideResult<()> {
|
||||||
let ctx = unsafe { self.as_ptr() };
|
let ptr = unsafe { self.as_ptr() };
|
||||||
let c_msg = CString::new(msg).to_nixide_result()?;
|
assert!(!ptr.is_null(), "");
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
sys::nix_set_err_msg(ctx, err.err_code(), c_msg.as_ptr());
|
sys::nix_set_err_msg(ptr, err.err_code(), msg.as_c_ptr()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -213,7 +217,7 @@ impl ErrorContext {
|
||||||
///
|
///
|
||||||
/// This function **never fails**.
|
/// This function **never fails**.
|
||||||
///
|
///
|
||||||
pub fn get_err(&self) -> Option<sys::NixErr> {
|
fn get_err(&self) -> Option<sys::NixErr> {
|
||||||
match unsafe { sys::nix_err_code(self.as_ptr()) } {
|
match unsafe { sys::nix_err_code(self.as_ptr()) } {
|
||||||
sys::NixErr::Ok => None,
|
sys::NixErr::Ok => None,
|
||||||
err => Some(err),
|
err => Some(err),
|
||||||
|
|
@ -250,7 +254,7 @@ impl ErrorContext {
|
||||||
/// Hence we can just test whether the returned pointer is a `NULL` pointer,
|
/// Hence we can just test whether the returned pointer is a `NULL` pointer,
|
||||||
/// and avoid passing in a [NixCContext] struct.
|
/// and avoid passing in a [NixCContext] struct.
|
||||||
///
|
///
|
||||||
pub fn get_msg(&self) -> Option<String> {
|
fn get_msg(&self) -> Option<String> {
|
||||||
// NOTE: an Err here only occurs when `self.get_code() == Ok(())`
|
// NOTE: an Err here only occurs when `self.get_code() == Ok(())`
|
||||||
let mut n: c_uint = 0;
|
let mut n: c_uint = 0;
|
||||||
let result = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
let result = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,6 @@ use crate::sys;
|
||||||
|
|
||||||
pub type NixideResult<T> = Result<T, NixideError>;
|
pub type NixideResult<T> = Result<T, NixideError>;
|
||||||
|
|
||||||
pub(crate) trait ToNixideResult<T> {
|
|
||||||
fn to_nixide_result(self) -> NixideResult<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ToNixideResult<T> for Result<T, std::ffi::NulError> {
|
|
||||||
fn to_nixide_result(self) -> NixideResult<T> {
|
|
||||||
Err(new_nixide_error!(StringNulByte))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum NixideError {
|
pub enum NixideError {
|
||||||
/// # Warning
|
/// # Warning
|
||||||
|
|
@ -144,3 +134,16 @@ impl Display for NixideError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub trait AsErr<T> {
|
||||||
|
// fn as_err(self) -> Result<(), T>;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl AsErr<NixideError> for Option<NixideError> {
|
||||||
|
// fn as_err(self) -> Result<(), NixideError> {
|
||||||
|
// match self {
|
||||||
|
// Some(err) => Err(err),
|
||||||
|
// None => Ok(()),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,6 @@ mod context;
|
||||||
mod nix_error;
|
mod nix_error;
|
||||||
|
|
||||||
pub(crate) use context::ErrorContext;
|
pub(crate) use context::ErrorContext;
|
||||||
|
pub(crate) use error::new_nixide_error;
|
||||||
pub use error::{NixideError, NixideResult};
|
pub use error::{NixideError, NixideResult};
|
||||||
pub(crate) use error::{ToNixideResult, new_nixide_error};
|
|
||||||
pub use nix_error::NixError;
|
pub use nix_error::NixError;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ffi::CString;
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::stdext::AsCPtr as _;
|
||||||
|
|
||||||
use super::Value;
|
use super::Value;
|
||||||
use crate::errors::{ErrorContext, ToNixideResult as _};
|
use crate::errors::ErrorContext;
|
||||||
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};
|
||||||
|
|
@ -21,6 +22,22 @@ pub struct EvalState {
|
||||||
store: Rc<RefCell<Store>>,
|
store: Rc<RefCell<Store>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl Clone for EvalState {
|
||||||
|
// 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::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 {
|
||||||
|
|
@ -70,8 +87,8 @@ impl EvalState {
|
||||||
/// 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 c_expr = CString::new(expr).to_nixide_result()?;
|
let expr = expr.as_c_ptr()?;
|
||||||
let c_path = CString::new(path).to_nixide_result()?;
|
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 (``)
|
||||||
|
|
@ -82,15 +99,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(),
|
value
|
||||||
self.as_ptr(),
|
|
||||||
c_expr.as_ptr(),
|
|
||||||
c_path.as_ptr(),
|
|
||||||
value.as_ptr(),
|
|
||||||
);
|
|
||||||
Value::from((value, self.inner_ref().clone()))
|
|
||||||
})
|
})
|
||||||
|
.map(|ptr| Value::from((ptr, self.inner_ref().clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ffi::CString;
|
|
||||||
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 std::rc::Rc;
|
||||||
|
|
||||||
use super::{NixThunk, NixValue, Value};
|
use super::{NixThunk, NixValue, Value};
|
||||||
use crate::errors::{ErrorContext, NixideError, ToNixideResult as _};
|
use crate::NixError;
|
||||||
use crate::stdext::CCharPtrExt;
|
use crate::errors::{ErrorContext, NixideError};
|
||||||
|
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::{NixError, NixideResult};
|
|
||||||
|
|
||||||
pub struct NixAttrs {
|
pub struct NixAttrs {
|
||||||
inner: NonNull<sys::NixValue>,
|
inner: NonNull<sys::NixValue>,
|
||||||
|
|
@ -171,58 +170,55 @@ impl NixAttrs {
|
||||||
Some(name)
|
Some(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<T>(&self, name: T) -> NixideResult<Option<Value>>
|
pub fn get<T>(&self, name: T) -> Option<Value>
|
||||||
where
|
where
|
||||||
T: AsRef<str>,
|
T: AsRef<str>,
|
||||||
{
|
{
|
||||||
let c_name = CString::new(name.as_ref()).to_nixide_result()?;
|
|
||||||
|
|
||||||
let result = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
let result = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_get_attr_byname(
|
sys::nix_get_attr_byname(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
self.state.borrow().as_ptr(),
|
self.state.borrow().as_ptr(),
|
||||||
c_name.as_ptr(),
|
name.as_ref()
|
||||||
|
.into_c_ptr()
|
||||||
|
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(inner) => Ok(Some(Value::from((inner, self.state.clone())))),
|
Ok(inner) => Some(Value::from((inner, self.state.clone()))),
|
||||||
|
|
||||||
Err(NixideError::NixError {
|
Err(NixideError::NixError {
|
||||||
err: NixError::KeyNotFound(_),
|
err: NixError::KeyNotFound(_),
|
||||||
..
|
..
|
||||||
}) => Ok(None),
|
}) => None,
|
||||||
Err(err) => Err(err),
|
Err(err) => panic_issue_call_failed!("{}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_lazy<T>(&self, name: T) -> NixideResult<Option<NixThunk>>
|
pub fn get_lazy<T>(&self, name: T) -> Option<NixThunk>
|
||||||
where
|
where
|
||||||
T: AsRef<str>,
|
T: AsRef<str>,
|
||||||
{
|
{
|
||||||
let c_name = CString::new(name.as_ref()).to_nixide_result()?;
|
|
||||||
|
|
||||||
let result = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
let result = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
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.borrow().as_ptr(),
|
self.state.borrow().as_ptr(),
|
||||||
c_name.as_ptr(),
|
name.as_ref()
|
||||||
|
.into_c_ptr()
|
||||||
|
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(inner) => Ok(Some(<NixThunk as NixValue>::from(
|
Ok(inner) => Some(<NixThunk as NixValue>::from(inner, self.state.clone())),
|
||||||
inner,
|
|
||||||
self.state.clone(),
|
|
||||||
))),
|
|
||||||
|
|
||||||
Err(NixideError::NixError {
|
Err(NixideError::NixError {
|
||||||
err: NixError::KeyNotFound(_),
|
err: NixError::KeyNotFound(_),
|
||||||
..
|
..
|
||||||
}) => Ok(None),
|
}) => None,
|
||||||
Err(err) => Err(err),
|
Err(err) => panic_issue_call_failed!("{}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use std::ffi::{CString, c_char};
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use crate::NixideResult;
|
use crate::NixideResult;
|
||||||
use crate::errors::{ErrorContext, ToNixideResult as _};
|
use crate::errors::ErrorContext;
|
||||||
|
use crate::stdext::AsCPtr as _;
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::util::wrap;
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr;
|
use crate::util::wrappers::AsInnerPtr;
|
||||||
|
|
@ -11,6 +11,19 @@ pub struct FetchersSettings {
|
||||||
inner: NonNull<sys::NixFetchersSettings>,
|
inner: NonNull<sys::NixFetchersSettings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl Clone for FetchersSettings {
|
||||||
|
// 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(),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl Drop for FetchersSettings {
|
impl Drop for FetchersSettings {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -37,13 +50,12 @@ impl AsInnerPtr<sys::NixFetchersSettings> for FetchersSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FetchersSettings {
|
impl FetchersSettings {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> NixideResult<Self> {
|
||||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_fetchers_settings_new(ctx.as_ptr())
|
sys::nix_fetchers_settings_new(ctx.as_ptr())
|
||||||
})
|
})?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Self { inner }
|
Ok(Self { inner })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
|
@ -55,22 +67,22 @@ impl FetchersSettings {
|
||||||
/// It is instead **exposed by the Nixide C API extensions.**
|
/// It is instead **exposed by the Nixide C API extensions.**
|
||||||
///
|
///
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn add_access_token(&self, token_name: &str, token_value: &str) -> NixideResult<()> {
|
pub fn add_access_token(self, token_name: &str, token_value: &str) -> NixideResult<Self> {
|
||||||
// XXX: TODO: have a dedicated `self.access_tokens: HashMap<String, String>` instead
|
// XXX: TODO: have a dedicated `self.access_tokens: HashMap<String, String>` instead
|
||||||
let c_name = CString::new(token_name).to_nixide_result()?;
|
let name_ptr = token_name.into_c_ptr()?;
|
||||||
let c_value = CString::new(token_value).to_nixide_result()?;
|
let value_ptr = token_value.into_c_ptr()?;
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_fetchers_settings_add_access_token(
|
sys::nix_fetchers_settings_add_access_token(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
c_name.as_ptr() as *mut c_char,
|
name_ptr,
|
||||||
c_value.as_ptr() as *mut c_char,
|
value_ptr,
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
|
@ -82,20 +94,16 @@ impl FetchersSettings {
|
||||||
/// It is instead **exposed by the Nixide C API extensions.**
|
/// It is instead **exposed by the Nixide C API extensions.**
|
||||||
///
|
///
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn remove_access_token(&self, token_name: &str) -> NixideResult<()> {
|
pub fn remove_access_token(self, token_name: &str) -> NixideResult<Self> {
|
||||||
// XXX: TODO: have a dedicated `self.access_tokens: HashMap<String, String>` instead
|
// XXX: TODO: have a dedicated `self.access_tokens: HashMap<String, String>` instead
|
||||||
let c_name = CString::new(token_name).to_nixide_result()?;
|
let name_ptr = token_name.into_c_ptr()?;
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_fetchers_settings_remove_access_token(
|
sys::nix_fetchers_settings_remove_access_token(ctx.as_ptr(), self.as_ptr(), name_ptr);
|
||||||
ctx.as_ptr(),
|
|
||||||
self.as_ptr(),
|
|
||||||
c_name.as_ptr() as *mut c_char,
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Nix C API Internals
|
/// # Nix C API Internals
|
||||||
|
|
@ -103,11 +111,14 @@ impl FetchersSettings {
|
||||||
/// This binding is **not provided by the Nix C API.**
|
/// This binding is **not provided by the Nix C API.**
|
||||||
/// It is instead **exposed by the Nixide C API extensions.**
|
/// It is instead **exposed by the Nixide C API extensions.**
|
||||||
///
|
///
|
||||||
pub fn allow_dirty(&self, value: bool) {
|
#[allow(unused)]
|
||||||
|
pub fn allow_dirty(self, value: bool) -> Self {
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_fetchers_settings_set_allow_dirty(ctx.as_ptr(), self.as_ptr(), value);
|
sys::nix_fetchers_settings_set_allow_dirty(ctx.as_ptr(), self.as_ptr(), value);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Nix C API Internals
|
/// # Nix C API Internals
|
||||||
|
|
@ -115,11 +126,14 @@ impl FetchersSettings {
|
||||||
/// This binding is **not provided by the Nix C API.**
|
/// This binding is **not provided by the Nix C API.**
|
||||||
/// It is instead **exposed by the Nixide C API extensions.**
|
/// It is instead **exposed by the Nixide C API extensions.**
|
||||||
///
|
///
|
||||||
pub fn warn_dirty(&self, value: bool) {
|
#[allow(unused)]
|
||||||
|
pub fn warn_dirty(self, value: bool) -> Self {
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_fetchers_settings_set_warn_dirty(ctx.as_ptr(), self.as_ptr(), value);
|
sys::nix_fetchers_settings_set_warn_dirty(ctx.as_ptr(), self.as_ptr(), value);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Nix C API Internals
|
/// # Nix C API Internals
|
||||||
|
|
@ -127,11 +141,14 @@ impl FetchersSettings {
|
||||||
/// This binding is **not provided by the Nix C API.**
|
/// This binding is **not provided by the Nix C API.**
|
||||||
/// It is instead **exposed by the Nixide C API extensions.**
|
/// It is instead **exposed by the Nixide C API extensions.**
|
||||||
///
|
///
|
||||||
pub fn allow_dirty_locks(&self, value: bool) {
|
#[allow(unused)]
|
||||||
|
pub fn allow_dirty_locks(self, value: bool) -> Self {
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_fetchers_settings_set_allow_dirty_locks(ctx.as_ptr(), self.as_ptr(), value);
|
sys::nix_fetchers_settings_set_allow_dirty_locks(ctx.as_ptr(), self.as_ptr(), value);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Nix C API Internals
|
/// # Nix C API Internals
|
||||||
|
|
@ -139,7 +156,8 @@ impl FetchersSettings {
|
||||||
/// This binding is **not provided by the Nix C API.**
|
/// This binding is **not provided by the Nix C API.**
|
||||||
/// It is instead **exposed by the Nixide C API extensions.**
|
/// It is instead **exposed by the Nixide C API extensions.**
|
||||||
///
|
///
|
||||||
pub fn trust_tarballs_from_git_forges(&self, value: bool) {
|
#[allow(unused)]
|
||||||
|
pub fn trust_tarballs_from_git_forges(self, value: bool) -> Self {
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_fetchers_settings_set_trust_tarballs_from_git_forges(
|
sys::nix_fetchers_settings_set_trust_tarballs_from_git_forges(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
|
|
@ -148,6 +166,8 @@ impl FetchersSettings {
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Nix C API Internals
|
/// # Nix C API Internals
|
||||||
|
|
@ -155,15 +175,17 @@ impl FetchersSettings {
|
||||||
/// This binding is **not provided by the Nix C API.**
|
/// This binding is **not provided by the Nix C API.**
|
||||||
/// It is instead **exposed by the Nixide C API extensions.**
|
/// It is instead **exposed by the Nixide C API extensions.**
|
||||||
///
|
///
|
||||||
pub fn tarball_ttl(&self, ttl: u32) {
|
#[allow(unused)]
|
||||||
|
pub fn tarball_ttl(self, ttl: u32) -> Self {
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_fetchers_settings_set_tarball_ttl(ctx.as_ptr(), self.as_ptr(), ttl);
|
sys::nix_fetchers_settings_set_tarball_ttl(ctx.as_ptr(), self.as_ptr(), ttl);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
|
||||||
/// Fails if the given `registry` contains a NUL byte.
|
/// Fails if the given `registry` contains a NUL byte.
|
||||||
///
|
///
|
||||||
/// # Nix C API Internals
|
/// # Nix C API Internals
|
||||||
|
|
@ -171,19 +193,20 @@ impl FetchersSettings {
|
||||||
/// This binding is **not provided by the Nix C API.**
|
/// This binding is **not provided by the Nix C API.**
|
||||||
/// It is instead **exposed by the Nixide C API extensions.**
|
/// It is instead **exposed by the Nixide C API extensions.**
|
||||||
///
|
///
|
||||||
pub fn global_flake_registry(&self, registry: &str) -> NixideResult<()> {
|
#[allow(unused)]
|
||||||
let c_registry = CString::new(registry).to_nixide_result()?;
|
pub fn global_flake_registry(self, registry: &str) -> NixideResult<Self> {
|
||||||
|
let registry_ptr = registry.into_c_ptr()?;
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_fetchers_settings_set_global_flake_registry(
|
sys::nix_fetchers_settings_set_global_flake_registry(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
c_registry.as_ptr() as *mut c_char,
|
registry_ptr,
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,6 +216,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fetchers_settings_new() {
|
fn fetchers_settings_new() {
|
||||||
let _ = FetchersSettings::new();
|
let _ = FetchersSettings::new().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
use std::ffi::{CString, c_char};
|
use std::ffi::c_char;
|
||||||
use std::ptr::{self, NonNull};
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use super::FlakeRef;
|
use super::{FlakeRef, FlakeSettings};
|
||||||
use crate::NixideResult;
|
use crate::NixideResult;
|
||||||
use crate::errors::{ErrorContext, ToNixideResult as _};
|
use crate::errors::ErrorContext;
|
||||||
|
use crate::stdext::AsCPtr as _;
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::util::wrap;
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr;
|
use crate::util::wrappers::AsInnerPtr;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum LockMode {
|
pub enum FlakeLockMode {
|
||||||
/// Configures [LockedFlake::lock] to make incremental changes to the lock file as needed. Changes are written to file.
|
/// Configures [LockedFlake::lock] to make incremental changes to the lock file as needed. Changes are written to file.
|
||||||
///
|
///
|
||||||
/// This is the default mode.
|
/// This is the default mode.
|
||||||
|
|
@ -27,7 +28,7 @@ pub enum LockMode {
|
||||||
|
|
||||||
/// Parameters that affect the locking of a flake.
|
/// Parameters that affect the locking of a flake.
|
||||||
pub struct FlakeLockFlags {
|
pub struct FlakeLockFlags {
|
||||||
inner: NonNull<sys::NixFlakeLockFlags>,
|
pub(crate) inner: NonNull<sys::NixFlakeLockFlags>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Clone for FlakeLockFlags {
|
// impl Clone for FlakeLockFlags {
|
||||||
|
|
@ -69,38 +70,12 @@ impl AsInnerPtr<sys::NixFlakeLockFlags> for FlakeLockFlags {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlakeLockFlags {
|
impl FlakeLockFlags {
|
||||||
pub fn new(mode: LockMode) -> Self {
|
pub fn new(settings: &FlakeSettings) -> NixideResult<Self> {
|
||||||
// NOTE: `nix_flake_lock_flags_new` is a simple initialisation
|
|
||||||
// NOTE: and will only fail if out of memory (hence we can "safely" unwrap).
|
|
||||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
// NOTE: `nix_flake_lock_flags_new` currently never uses the `settings`
|
sys::nix_flake_lock_flags_new(ctx.as_ptr(), settings.as_ptr())
|
||||||
// NOTE: parameter, hence providing a null pointer is fine.
|
})?;
|
||||||
sys::nix_flake_lock_flags_new(ctx.as_ptr(), ptr::null_mut())
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let self_ = FlakeLockFlags { inner };
|
Ok(FlakeLockFlags { inner })
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| {
|
|
||||||
match mode {
|
|
||||||
LockMode::WriteAsNeeded => unsafe {
|
|
||||||
sys::nix_flake_lock_flags_set_mode_write_as_needed(ctx.as_ptr(), self_.as_ptr())
|
|
||||||
},
|
|
||||||
LockMode::Virtual => unsafe {
|
|
||||||
sys::nix_flake_lock_flags_set_mode_virtual(ctx.as_ptr(), self_.as_ptr())
|
|
||||||
},
|
|
||||||
LockMode::Check => unsafe {
|
|
||||||
sys::nix_flake_lock_flags_set_mode_check(ctx.as_ptr(), self_.as_ptr())
|
|
||||||
},
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
self_
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default() -> Self {
|
|
||||||
Self::new(LockMode::WriteAsNeeded)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds an input override to the lock file that will be produced.
|
/// Adds an input override to the lock file that will be produced.
|
||||||
|
|
@ -119,13 +94,13 @@ impl FlakeLockFlags {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn override_input(self, input: &str, flakeref: &FlakeRef) -> NixideResult<Self> {
|
pub fn override_input(self, input: &str, flakeref: &FlakeRef) -> NixideResult<Self> {
|
||||||
// XXX: TODO: should `input` be wrapped as `format!("inputs.{input}")`?
|
// XXX: TODO: should `input` be wrapped as `format!("inputs.{input}")`?
|
||||||
let c_input = CString::new(input).to_nixide_result()?;
|
let input_path = input.as_c_ptr()?;
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_flake_lock_flags_add_input_override(
|
sys::nix_flake_lock_flags_add_input_override(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
c_input.as_ptr(),
|
input_path,
|
||||||
flakeref.as_ptr(),
|
flakeref.as_ptr(),
|
||||||
);
|
);
|
||||||
})?;
|
})?;
|
||||||
|
|
@ -147,14 +122,29 @@ impl FlakeLockFlags {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn update_input(self, input: &str) -> NixideResult<Self> {
|
pub fn update_input(self, input: &str) -> NixideResult<Self> {
|
||||||
// XXX: TODO: should `input` be wrapped as `format!("inputs.{input}")`?
|
// XXX: TODO: should `input` be wrapped as `format!("inputs.{input}")`?
|
||||||
let c_input = CString::new(input).to_nixide_result()?;
|
let input_path = input.as_c_ptr()?;
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_flake_lock_flags_add_input_update(
|
sys::nix_flake_lock_flags_add_input_update(ctx.as_ptr(), self.as_ptr(), input_path);
|
||||||
ctx.as_ptr(),
|
})?;
|
||||||
self.as_ptr(),
|
|
||||||
c_input.as_ptr(),
|
Ok(self)
|
||||||
);
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
pub fn set_mode(self, mode: FlakeLockMode) -> NixideResult<Self> {
|
||||||
|
wrap::nix_fn!(|ctx: &ErrorContext| {
|
||||||
|
match mode {
|
||||||
|
FlakeLockMode::WriteAsNeeded => unsafe {
|
||||||
|
sys::nix_flake_lock_flags_set_mode_write_as_needed(ctx.as_ptr(), self.as_ptr())
|
||||||
|
},
|
||||||
|
FlakeLockMode::Virtual => unsafe {
|
||||||
|
sys::nix_flake_lock_flags_set_mode_virtual(ctx.as_ptr(), self.as_ptr())
|
||||||
|
},
|
||||||
|
FlakeLockMode::Check => unsafe {
|
||||||
|
sys::nix_flake_lock_flags_set_mode_check(ctx.as_ptr(), self.as_ptr())
|
||||||
|
},
|
||||||
|
};
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
|
@ -290,13 +280,13 @@ impl FlakeLockFlags {
|
||||||
///
|
///
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn input_lock_file_path(self, path: &str) -> NixideResult<Self> {
|
pub fn input_lock_file_path(self, path: &str) -> NixideResult<Self> {
|
||||||
let c_path = CString::new(path).to_nixide_result()?;
|
let path_ptr = path.as_c_ptr()? as *mut c_char;
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_flake_lock_flags_set_reference_lock_file_path(
|
sys::nix_flake_lock_flags_set_reference_lock_file_path(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
c_path.as_ptr() as *mut c_char,
|
path_ptr,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -314,13 +304,13 @@ impl FlakeLockFlags {
|
||||||
///
|
///
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn output_lock_file_path(self, path: &str) -> NixideResult<Self> {
|
pub fn output_lock_file_path(self, path: &str) -> NixideResult<Self> {
|
||||||
let c_path = CString::new(path).to_nixide_result()?;
|
let path_ptr = path.as_c_ptr()? as *mut c_char;
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_flake_lock_flags_set_output_lock_file_path(
|
sys::nix_flake_lock_flags_set_output_lock_file_path(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
c_path.as_ptr() as *mut c_char,
|
path_ptr,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use std::ffi::CString;
|
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use crate::NixideResult;
|
use crate::NixideResult;
|
||||||
use crate::errors::{ErrorContext, ToNixideResult as _};
|
use crate::errors::ErrorContext;
|
||||||
|
use crate::stdext::AsCPtr as _;
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::util::wrap;
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr;
|
use crate::util::wrappers::AsInnerPtr;
|
||||||
|
|
@ -86,12 +86,12 @@ impl FlakeSettings {
|
||||||
///
|
///
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn commit_lock_file_summary(self, summary: &str) -> NixideResult<Self> {
|
pub fn commit_lock_file_summary(self, summary: &str) -> NixideResult<Self> {
|
||||||
let c_summary = CString::new(summary).to_nixide_result()?;
|
let summary_ptr = summary.into_c_ptr()?;
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_flake_settings_set_commit_lock_file_summary(
|
sys::nix_flake_settings_set_commit_lock_file_summary(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
c_summary.as_ptr().cast_mut(),
|
summary_ptr,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,35 @@
|
||||||
use std::ptr::NonNull;
|
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::sys;
|
||||||
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr;
|
use crate::util::wrappers::AsInnerPtr;
|
||||||
|
|
||||||
pub struct FlakeRef {
|
pub struct FlakeRef {
|
||||||
inner: NonNull<sys::NixFlakeReference>,
|
inner: NonNull<sys::NixFlakeReference>,
|
||||||
fragment: String,
|
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 {
|
impl Drop for FlakeRef {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -33,13 +55,45 @@ impl AsInnerPtr<sys::NixFlakeReference> for FlakeRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: TODO: is it possible to get the URI string itself? (minus the fragment part?)
|
|
||||||
impl FlakeRef {
|
impl FlakeRef {
|
||||||
#[inline]
|
/// Parse a flake reference from a string.
|
||||||
pub(crate) fn new(inner: NonNull<sys::NixFlakeReference>, fragment: String) -> Self {
|
/// The string must be a valid flake reference, such as `github:owner/repo`.
|
||||||
Self { inner, fragment }
|
/// 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.
|
/// Get a shared reference to the URI fragment part.
|
||||||
///
|
///
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
||||||
use std::ffi::{CString, c_void};
|
|
||||||
use std::path::Path;
|
|
||||||
use std::ptr::{self, NonNull, null_mut};
|
|
||||||
|
|
||||||
use super::{FetchersSettings, FlakeRef, FlakeRefParseFlags};
|
|
||||||
use crate::errors::{ErrorContext, NixideResult, ToNixideResult as _, new_nixide_error};
|
|
||||||
use crate::sys;
|
|
||||||
use crate::util::wrap;
|
|
||||||
use crate::util::wrappers::AsInnerPtr;
|
|
||||||
|
|
||||||
pub struct FlakeRefBuilder {
|
|
||||||
reference: String,
|
|
||||||
fetch_settings: FetchersSettings,
|
|
||||||
parse_flags: FlakeRefParseFlags,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FlakeRefBuilder {
|
|
||||||
/// 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 new<S: AsRef<str>>(reference: S) -> Self {
|
|
||||||
Self {
|
|
||||||
reference: reference.as_ref().to_string(),
|
|
||||||
fetch_settings: FetchersSettings::new(),
|
|
||||||
parse_flags: FlakeRefParseFlags::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build(&self) -> NixideResult<FlakeRef> {
|
|
||||||
let c_reference = CString::new(self.reference.as_str()).to_nixide_result()?;
|
|
||||||
|
|
||||||
let mut ptr: *mut sys::NixFlakeReference = null_mut();
|
|
||||||
let fragment = wrap::nix_string_callback!(
|
|
||||||
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
|
||||||
// NOTE: `nix_flake_reference_and_fragment_from_string` currently
|
|
||||||
// NOTE: never uses the `flake_settings` parameter, hence providing
|
|
||||||
// NOTE: a null pointer instead is fine.
|
|
||||||
sys::nix_flake_reference_and_fragment_from_string(
|
|
||||||
ctx.as_ptr(),
|
|
||||||
self.fetch_settings.as_ptr(),
|
|
||||||
ptr::null_mut(),
|
|
||||||
self.parse_flags.as_ptr(),
|
|
||||||
c_reference.as_ptr(),
|
|
||||||
self.reference.len(),
|
|
||||||
&mut ptr,
|
|
||||||
Some(callback),
|
|
||||||
userdata as *mut c_void,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)?;
|
|
||||||
|
|
||||||
match NonNull::new(ptr) {
|
|
||||||
Some(inner) => Ok(FlakeRef::new(inner, fragment)),
|
|
||||||
None => Err(new_nixide_error!(NullPtr)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn base_directory<P: AsRef<Path>>(mut self, path: P) -> NixideResult<Self> {
|
|
||||||
self.parse_flags
|
|
||||||
.base_directory(&path.as_ref().to_string_lossy())?;
|
|
||||||
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn global_flake_registry(self, registry: &str) -> NixideResult<Self> {
|
|
||||||
self.fetch_settings.global_flake_registry(registry)?;
|
|
||||||
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn allow_dirty(self, value: bool) -> Self {
|
|
||||||
self.fetch_settings.allow_dirty(value);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn warn_dirty(self, value: bool) -> Self {
|
|
||||||
self.fetch_settings.warn_dirty(value);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn allow_dirty_locks(self, value: bool) -> Self {
|
|
||||||
self.fetch_settings.allow_dirty_locks(value);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn trust_tarballs_from_git_forges(self, value: bool) -> Self {
|
|
||||||
self.fetch_settings.trust_tarballs_from_git_forges(value);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tarball_ttl(self, ttl: u32) -> Self {
|
|
||||||
self.fetch_settings.tarball_ttl(ttl);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +1,36 @@
|
||||||
use std::ffi::CString;
|
use std::ffi::c_char;
|
||||||
use std::ptr::{self, NonNull};
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use crate::errors::{ErrorContext, ToNixideResult as _};
|
use super::FlakeSettings;
|
||||||
|
use crate::NixideResult;
|
||||||
|
use crate::errors::ErrorContext;
|
||||||
|
use crate::sys;
|
||||||
use crate::util::wrap;
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr;
|
use crate::util::wrappers::AsInnerPtr;
|
||||||
use crate::{NixideResult, sys};
|
|
||||||
|
|
||||||
/// Parameters for parsing a flake reference.
|
/// Parameters for parsing a flake reference.
|
||||||
///
|
|
||||||
/// # Nix C API Internals
|
|
||||||
///
|
|
||||||
/// Currently the Nix C API only uses this for storing
|
|
||||||
/// a base directory... Kinda overkill no? ;w;
|
|
||||||
///
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
// pub(super) struct FlakeRefParseFlags {
|
|
||||||
pub struct FlakeRefParseFlags {
|
pub struct FlakeRefParseFlags {
|
||||||
// DEBUG (go back to pub(super) soon)
|
|
||||||
inner: NonNull<sys::NixFlakeReferenceParseFlags>,
|
inner: NonNull<sys::NixFlakeReferenceParseFlags>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl Clone for FlakeReferenceParseFlags {
|
||||||
|
// 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(),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
impl Drop for FlakeRefParseFlags {
|
impl Drop for FlakeRefParseFlags {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
sys::nix_flake_reference_parse_flags_free(self.as_ptr());
|
sys::nix_flake_reference_parse_flags_free(self.inner.as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -46,40 +53,24 @@ impl AsInnerPtr<sys::NixFlakeReferenceParseFlags> for FlakeRefParseFlags {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlakeRefParseFlags {
|
impl FlakeRefParseFlags {
|
||||||
pub fn new() -> Self {
|
pub fn new(settings: &FlakeSettings) -> NixideResult<Self> {
|
||||||
// NOTE: `nix_flake_reference_parse_flags_new` is a simple initialisation
|
|
||||||
// NOTE: and will only fail if out of memory (hence we can "safely" unwrap).
|
|
||||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
// NOTE: `nix_flake_reference_parse_flags_new` currently never uses the `settings`
|
sys::nix_flake_reference_parse_flags_new(ctx.as_ptr(), settings.as_ptr())
|
||||||
// NOTE: parameter, hence providing a null pointer is fine.
|
})?;
|
||||||
sys::nix_flake_reference_parse_flags_new(ctx.as_ptr(), ptr::null_mut())
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Self { inner }
|
Ok(Self { inner })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the [base directory](https://nix.dev/manual/nix/latest/glossary#gloss-base-directory)
|
/// Sets the [base directory](https://nix.dev/manual/nix/latest/glossary#gloss-base-directory)
|
||||||
/// for resolving local flake references.
|
/// for resolving local flake references.
|
||||||
///
|
pub fn set_base_directory(&mut self, base_directory: &str) -> NixideResult<()> {
|
||||||
/// # Nix C API Internals
|
|
||||||
///
|
|
||||||
/// If `set_base_directory` is never called, the base directory defaults
|
|
||||||
/// to the current working directory (see `libutil/filesystem.cc:absPath`).
|
|
||||||
///
|
|
||||||
pub fn base_directory(&mut self, base_directory: &str) -> NixideResult<()> {
|
|
||||||
let c_base_directory = CString::new(base_directory).to_nixide_result()?;
|
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_flake_reference_parse_flags_set_base_directory(
|
sys::nix_flake_reference_parse_flags_set_base_directory(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
self.as_ptr(),
|
self.as_ptr(),
|
||||||
c_base_directory.as_ptr(),
|
base_directory.as_ptr() as *const c_char,
|
||||||
base_directory.len(),
|
base_directory.len(),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
|
// XXX: TODO: find a way to read directly from FlakeSettings and FetchersSettings (the C++ classes)
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ptr::{self, NonNull};
|
use std::ptr::NonNull;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::{FlakeLockFlags, FlakeRef, FlakeRefBuilder, FlakeSettings};
|
use super::{FetchersSettings, FlakeLockFlags, FlakeLockMode, FlakeRef, FlakeSettings};
|
||||||
use crate::errors::ErrorContext;
|
use crate::errors::ErrorContext;
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::util::wrap;
|
use crate::util::wrap;
|
||||||
|
|
@ -15,6 +17,7 @@ pub struct LockedFlake {
|
||||||
flakeref: FlakeRef,
|
flakeref: FlakeRef,
|
||||||
state: Rc<RefCell<NonNull<sys::EvalState>>>,
|
state: Rc<RefCell<NonNull<sys::EvalState>>>,
|
||||||
lock_flags: FlakeLockFlags,
|
lock_flags: FlakeLockFlags,
|
||||||
|
fetch_settings: FetchersSettings,
|
||||||
flake_settings: FlakeSettings,
|
flake_settings: FlakeSettings,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,19 +48,19 @@ impl AsInnerPtr<sys::NixLockedFlake> for LockedFlake {
|
||||||
|
|
||||||
impl LockedFlake {
|
impl LockedFlake {
|
||||||
pub fn lock(
|
pub fn lock(
|
||||||
lock_flags: FlakeLockFlags,
|
mode: FlakeLockMode,
|
||||||
flakeref: FlakeRef,
|
flakeref: FlakeRef,
|
||||||
state: &EvalState,
|
state: &EvalState,
|
||||||
) -> NixideResult<LockedFlake> {
|
) -> NixideResult<LockedFlake> {
|
||||||
let state_inner = state.inner_ref();
|
let state_inner = state.inner_ref();
|
||||||
|
let fetch_settings = FetchersSettings::new()?;
|
||||||
let flake_settings = FlakeSettings::new()?;
|
let flake_settings = FlakeSettings::new()?;
|
||||||
|
let lock_flags = FlakeLockFlags::new(&flake_settings)?.set_mode(mode)?;
|
||||||
|
|
||||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
// NOTE: `nix_flake_lock` currently never uses the `fetchSettings`
|
|
||||||
// NOTE: parameter, hence providing a null pointer instead is fine.
|
|
||||||
sys::nix_flake_lock(
|
sys::nix_flake_lock(
|
||||||
ctx.as_ptr(),
|
ctx.as_ptr(),
|
||||||
ptr::null_mut(),
|
fetch_settings.as_ptr(),
|
||||||
flake_settings.as_ptr(),
|
flake_settings.as_ptr(),
|
||||||
state_inner.borrow().as_ptr(),
|
state_inner.borrow().as_ptr(),
|
||||||
lock_flags.as_ptr(),
|
lock_flags.as_ptr(),
|
||||||
|
|
@ -70,6 +73,7 @@ impl LockedFlake {
|
||||||
flakeref,
|
flakeref,
|
||||||
state: state_inner.clone(),
|
state: state_inner.clone(),
|
||||||
lock_flags,
|
lock_flags,
|
||||||
|
fetch_settings,
|
||||||
flake_settings,
|
flake_settings,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -94,8 +98,8 @@ mod tests {
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
|
||||||
use super::{FlakeLockFlags, FlakeRefBuilder, FlakeSettings, LockedFlake};
|
use super::{FetchersSettings, FlakeLockFlags, FlakeRef, FlakeSettings, LockedFlake};
|
||||||
use crate::flake::LockMode;
|
use crate::flake::{FlakeLockMode, FlakeRefParseFlags};
|
||||||
use crate::{EvalStateBuilder, Store, Value, set_global_setting};
|
use crate::{EvalStateBuilder, Store, Value, set_global_setting};
|
||||||
|
|
||||||
static INIT: Once = Once::new();
|
static INIT: Once = Once::new();
|
||||||
|
|
@ -157,16 +161,12 @@ mod tests {
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// let flakeref = FlakeRefBuilder::new(format!("path:{}#subthing", tmp_dir.path().display())) // DEBUG
|
let flakeref =
|
||||||
let flakeref = FlakeRefBuilder::new(format!("{}#subthing", tmp_dir.path().display()))
|
FlakeRef::parse(&format!("path:{}#subthing", tmp_dir.path().display())).unwrap();
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(flakeref.fragment(), "subthing");
|
assert_eq!(flakeref.fragment(), "subthing");
|
||||||
|
|
||||||
let flake_lock_flags = FlakeLockFlags::new(LockMode::WriteAsNeeded);
|
let outputs = LockedFlake::lock(FlakeLockMode::WriteAsNeeded, flakeref, &eval_state)
|
||||||
|
|
||||||
let outputs = LockedFlake::lock(flake_lock_flags, flakeref, &eval_state)
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.outputs()
|
.outputs()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -175,203 +175,215 @@ mod tests {
|
||||||
if let Value::Attrs(outputs) = outputs {
|
if let Value::Attrs(outputs) = outputs {
|
||||||
let value = outputs.get("hello").unwrap();
|
let value = outputs.get("hello").unwrap();
|
||||||
|
|
||||||
assert!(matches!(value, Some(Value::String(_))));
|
assert!(matches!(value, Value::String(_)));
|
||||||
if let Some(Value::String(value)) = value {
|
if let Value::String(value) = value {
|
||||||
assert_eq!(value.as_string(), "world");
|
assert_eq!(value.as_string(), "world");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test] # DEBUG (too lazy to keep fixing this function...)
|
#[test]
|
||||||
// fn flake_lock_load_flake_with_flags() {
|
fn flake_lock_load_flake_with_flags() {
|
||||||
// init();
|
init();
|
||||||
|
|
||||||
// let store_ref = Store::default().unwrap();
|
let store_ref = Store::default().unwrap();
|
||||||
// let flake_settings = FlakeSettings::new().unwrap();
|
let fetchers_settings = FetchersSettings::new().unwrap();
|
||||||
// let eval_state = EvalStateBuilder::new(store_ref.clone())
|
let flake_settings = FlakeSettings::new().unwrap();
|
||||||
// .unwrap()
|
let eval_state = EvalStateBuilder::new(store_ref.clone())
|
||||||
// .set_flake_settings(&flake_settings)
|
.unwrap()
|
||||||
// .unwrap()
|
.set_flake_settings(&flake_settings)
|
||||||
// .build()
|
.unwrap()
|
||||||
// .unwrap();
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// let tmp_dir = tempfile::tempdir().unwrap();
|
let tmp_dir = tempfile::tempdir().unwrap();
|
||||||
|
|
||||||
// let flake_dir_a = tmp_dir.path().join("a");
|
let flake_dir_a = tmp_dir.path().join("a");
|
||||||
// let flake_dir_b = tmp_dir.path().join("b");
|
let flake_dir_b = tmp_dir.path().join("b");
|
||||||
// let flake_dir_c = tmp_dir.path().join("c");
|
let flake_dir_c = tmp_dir.path().join("c");
|
||||||
|
|
||||||
// std::fs::create_dir_all(&flake_dir_a).unwrap();
|
std::fs::create_dir_all(&flake_dir_a).unwrap();
|
||||||
// std::fs::create_dir_all(&flake_dir_b).unwrap();
|
std::fs::create_dir_all(&flake_dir_b).unwrap();
|
||||||
// std::fs::create_dir_all(&flake_dir_c).unwrap();
|
std::fs::create_dir_all(&flake_dir_c).unwrap();
|
||||||
|
|
||||||
// let flake_dir_a_str = flake_dir_a.to_str().unwrap();
|
let flake_dir_a_str = flake_dir_a.to_str().unwrap();
|
||||||
// let flake_dir_c_str = flake_dir_c.to_str().unwrap();
|
let flake_dir_c_str = flake_dir_c.to_str().unwrap();
|
||||||
// assert!(!flake_dir_a_str.is_empty());
|
assert!(!flake_dir_a_str.is_empty());
|
||||||
// assert!(!flake_dir_c_str.is_empty());
|
assert!(!flake_dir_c_str.is_empty());
|
||||||
|
|
||||||
// // a
|
// a
|
||||||
// std::fs::write(
|
std::fs::write(
|
||||||
// tmp_dir.path().join("a/flake.nix"),
|
tmp_dir.path().join("a/flake.nix"),
|
||||||
// r#"
|
r#"
|
||||||
// {
|
{
|
||||||
// inputs.b.url = "@flake_dir_b@";
|
inputs.b.url = "@flake_dir_b@";
|
||||||
// outputs = { b, ... }: {
|
outputs = { b, ... }: {
|
||||||
// hello = b.hello;
|
hello = b.hello;
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
// "#
|
"#
|
||||||
// .replace("@flake_dir_b@", flake_dir_b.to_str().unwrap()),
|
.replace("@flake_dir_b@", flake_dir_b.to_str().unwrap()),
|
||||||
// )
|
)
|
||||||
// .unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// // b
|
// b
|
||||||
// std::fs::write(
|
std::fs::write(
|
||||||
// tmp_dir.path().join("b/flake.nix"),
|
tmp_dir.path().join("b/flake.nix"),
|
||||||
// r#"
|
r#"
|
||||||
// {
|
{
|
||||||
// outputs = { ... }: {
|
outputs = { ... }: {
|
||||||
// hello = "ALICE";
|
hello = "ALICE";
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
// "#,
|
"#,
|
||||||
// )
|
)
|
||||||
// .unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// // c
|
// c
|
||||||
// std::fs::write(
|
std::fs::write(
|
||||||
// tmp_dir.path().join("c/flake.nix"),
|
tmp_dir.path().join("c/flake.nix"),
|
||||||
// r#"
|
r#"
|
||||||
// {
|
{
|
||||||
// outputs = { ... }: {
|
outputs = { ... }: {
|
||||||
// hello = "Claire";
|
hello = "Claire";
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
// "#,
|
"#,
|
||||||
// )
|
)
|
||||||
// .unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// let flakeref_a = FlakeRefBuilder::new(format!("path:{}", &flake_dir_a_str))
|
let mut flake_lock_flags = FlakeLockFlags::new(&flake_settings).unwrap();
|
||||||
// .build()
|
|
||||||
// .unwrap();
|
|
||||||
|
|
||||||
// assert_eq!(flakeref_a.fragment(), "");
|
let mut flake_reference_parse_flags = FlakeRefParseFlags::new(&flake_settings).unwrap();
|
||||||
|
|
||||||
// // Step 1: Do not update (check), fails
|
flake_reference_parse_flags
|
||||||
// let mut flake_lock_flags = FlakeLockFlags::new(LockMode::Check);
|
.set_base_directory(tmp_dir.path().to_str().unwrap())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state);
|
let flakeref_a = FlakeRef::parse(&format!("path:{}", &flake_dir_a_str)).unwrap();
|
||||||
// // Has not been locked and would need to write a lock file.
|
|
||||||
// assert!(locked_flake.is_err());
|
|
||||||
// let saved_err = match locked_flake {
|
|
||||||
// Ok(_) => panic!("Expected error, but got Ok"),
|
|
||||||
// Err(e) => e,
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Step 2: Update but do not write, succeeds
|
assert_eq!(flakeref_a.fragment(), "");
|
||||||
// let flake_lock_flags = FlakeLockFlags::new(LockMode::Virtual);
|
|
||||||
|
|
||||||
// let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
// Step 1: Do not update (check), fails
|
||||||
|
flake_lock_flags.set_mode(FlakeLockMode::Check).unwrap();
|
||||||
|
|
||||||
// let outputs = locked_flake.outputs().unwrap();
|
let locked_flake = LockedFlake::lock(FlakeLockMode::Check, flakeref_a, &eval_state);
|
||||||
|
// Has not been locked and would need to write a lock file.
|
||||||
|
assert!(locked_flake.is_err());
|
||||||
|
let saved_err = match locked_flake {
|
||||||
|
Ok(_) => panic!("Expected error, but got Ok"),
|
||||||
|
Err(e) => e,
|
||||||
|
};
|
||||||
|
|
||||||
// assert!(matches!(outputs, Value::Attrs(_)));
|
// Step 2: Update but do not write, succeeds
|
||||||
// if let Value::Attrs(outputs) = outputs {
|
flake_lock_flags.set_mode(FlakeLockMode::Virtual).unwrap();
|
||||||
// let value = outputs.get("hello").unwrap();
|
|
||||||
|
|
||||||
// assert!(matches!(value, Value::String(_)));
|
let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
||||||
// if let Value::String(value) = value {
|
|
||||||
// assert_eq!(value.as_string(), "ALICE");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Step 3: The lock was not written, so Step 1 would fail again
|
let outputs = locked_flake.outputs().unwrap();
|
||||||
// let flake_lock_flags = FlakeLockFlags::new(LockMode::Check);
|
|
||||||
|
|
||||||
// let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state);
|
assert!(matches!(outputs, Value::Attrs(_)));
|
||||||
// // Has not been locked and would need to write a lock file.
|
if let Value::Attrs(outputs) = outputs {
|
||||||
// match locked_flake {
|
let value = outputs.get("hello").unwrap();
|
||||||
// Ok(_) => panic!("Expected error, but got Ok"),
|
|
||||||
// Err(e) => {
|
|
||||||
// assert_eq!(e.to_string(), saved_err.to_string());
|
|
||||||
// },
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Step 4: Update and write, succeeds
|
assert!(matches!(value, Value::String(_)));
|
||||||
// let flake_lock_flags = FlakeLockFlags::new(LockMode::WriteAsNeeded);
|
if let Value::String(value) = value {
|
||||||
|
assert_eq!(value.as_string(), "ALICE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
// Step 3: The lock was not written, so Step 1 would fail again
|
||||||
|
flake_lock_flags.set_mode(FlakeLockMode::Check).unwrap();
|
||||||
|
|
||||||
// let outputs = locked_flake.outputs().unwrap();
|
let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state);
|
||||||
|
// Has not been locked and would need to write a lock file.
|
||||||
|
match locked_flake {
|
||||||
|
Ok(_) => panic!("Expected error, but got Ok"),
|
||||||
|
Err(e) => {
|
||||||
|
assert_eq!(e.to_string(), saved_err.to_string());
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// assert!(matches!(outputs, Value::Attrs(_)));
|
// Step 4: Update and write, succeeds
|
||||||
// if let Value::Attrs(outputs) = outputs {
|
flake_lock_flags
|
||||||
// let value = outputs.get("hello").unwrap();
|
.set_mode(FlakeLockMode::WriteAsNeeded)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// assert!(matches!(value, Value::String(_)));
|
let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
||||||
// if let Value::String(value) = value {
|
|
||||||
// assert_eq!(value.as_string(), "ALICE");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Step 5: Lock was written, so Step 1 succeeds
|
let outputs = locked_flake.outputs().unwrap();
|
||||||
// let flake_lock_flags = FlakeLockFlags::new(LockMode::Check);
|
|
||||||
|
|
||||||
// let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
assert!(matches!(outputs, Value::Attrs(_)));
|
||||||
|
if let Value::Attrs(outputs) = outputs {
|
||||||
|
let value = outputs.get("hello").unwrap();
|
||||||
|
|
||||||
// let outputs = locked_flake.outputs().unwrap();
|
assert!(matches!(value, Value::String(_)));
|
||||||
|
if let Value::String(value) = value {
|
||||||
|
assert_eq!(value.as_string(), "ALICE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// assert!(matches!(outputs, Value::Attrs(_)));
|
// Step 5: Lock was written, so Step 1 succeeds
|
||||||
// if let Value::Attrs(outputs) = outputs {
|
flake_lock_flags.set_mode(FlakeLockMode::Check).unwrap();
|
||||||
// let value = outputs.get("hello").unwrap();
|
|
||||||
|
|
||||||
// assert!(matches!(value, Value::String(_)));
|
let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
||||||
// if let Value::String(value) = value {
|
|
||||||
// assert_eq!(value.as_string(), "ALICE");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Step 6: Lock with override, do not write
|
let outputs = locked_flake.outputs().unwrap();
|
||||||
|
|
||||||
// // This shouldn't matter; write_as_needed will be overridden
|
assert!(matches!(outputs, Value::Attrs(_)));
|
||||||
// let flake_lock_flags = FlakeLockFlags::new(LockMode::WriteAsNeeded);
|
if let Value::Attrs(outputs) = outputs {
|
||||||
|
let value = outputs.get("hello").unwrap();
|
||||||
|
|
||||||
// let flakeref_c = FlakeRefBuilder::new(format!("path:{}", &flake_dir_c_str))
|
assert!(matches!(value, Value::String(_)));
|
||||||
// .build()
|
if let Value::String(value) = value {
|
||||||
// .unwrap();
|
assert_eq!(value.as_string(), "ALICE");
|
||||||
// assert_eq!(flakeref_c.fragment(), "");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// flake_lock_flags.override_input("b", &flakeref_c).unwrap();
|
// Step 6: Lock with override, do not write
|
||||||
|
|
||||||
// let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
// This shouldn't matter; write_as_needed will be overridden
|
||||||
|
flake_lock_flags
|
||||||
|
.set_mode(FlakeLockMode::WriteAsNeeded)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// let outputs = locked_flake.outputs().unwrap();
|
let flakeref_c = FlakeRef::parse(&format!("path:{}", &flake_dir_c_str)).unwrap();
|
||||||
|
assert_eq!(flakeref_c.fragment(), "");
|
||||||
|
|
||||||
// assert!(matches!(outputs, Value::Attrs(_)));
|
flake_lock_flags.override_input("b", &flakeref_c).unwrap();
|
||||||
// if let Value::Attrs(outputs) = outputs {
|
|
||||||
// let value = outputs.get("hello").unwrap();
|
|
||||||
|
|
||||||
// assert!(matches!(value, Value::String(_)));
|
let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
||||||
// if let Value::String(value) = value {
|
|
||||||
// assert_eq!(value.as_string(), "Claire");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Step 7: Override was not written; lock still points to b
|
let outputs = locked_flake.outputs().unwrap();
|
||||||
// let flake_lock_flags = FlakeLockFlags::new(LockMode::Check);
|
|
||||||
|
|
||||||
// let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
assert!(matches!(outputs, Value::Attrs(_)));
|
||||||
|
if let Value::Attrs(outputs) = outputs {
|
||||||
|
let value = outputs.get("hello").unwrap();
|
||||||
|
|
||||||
// let outputs = locked_flake.outputs().unwrap();
|
assert!(matches!(value, Value::String(_)));
|
||||||
|
if let Value::String(value) = value {
|
||||||
|
assert_eq!(value.as_string(), "Claire");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// assert!(matches!(outputs, Value::Attrs(_)));
|
// Can't delete overrides, so trash it
|
||||||
// if let Value::Attrs(outputs) = outputs {
|
let mut flake_lock_flags = FlakeLockFlags::new(&flake_settings).unwrap();
|
||||||
// let value = outputs.get("hello").unwrap();
|
|
||||||
|
|
||||||
// assert!(matches!(value, Value::String(_)));
|
// Step 7: Override was not written; lock still points to b
|
||||||
// if let Value::String(value) = value {
|
flake_lock_flags.set_mode(FlakeLockMode::Check).unwrap();
|
||||||
// assert_eq!(value.as_string(), "ALICE");
|
|
||||||
// }
|
let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap();
|
||||||
// }
|
|
||||||
// }
|
let outputs = locked_flake.outputs().unwrap();
|
||||||
|
|
||||||
|
assert!(matches!(outputs, Value::Attrs(_)));
|
||||||
|
if let Value::Attrs(outputs) = outputs {
|
||||||
|
let value = outputs.get("hello").unwrap();
|
||||||
|
|
||||||
|
assert!(matches!(value, Value::String(_)));
|
||||||
|
if let Value::String(value) = value {
|
||||||
|
assert_eq!(value.as_string(), "ALICE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,12 @@ mod fetchers_settings;
|
||||||
mod flake_lock_flags;
|
mod flake_lock_flags;
|
||||||
mod flake_settings;
|
mod flake_settings;
|
||||||
mod flakeref;
|
mod flakeref;
|
||||||
mod flakeref_builder;
|
|
||||||
mod flakeref_parse_flags;
|
mod flakeref_parse_flags;
|
||||||
mod locked_flake;
|
mod locked_flake;
|
||||||
|
|
||||||
pub use fetchers_settings::FetchersSettings;
|
use fetchers_settings::FetchersSettings;
|
||||||
pub use flake_lock_flags::{FlakeLockFlags, LockMode};
|
use flake_lock_flags::{FlakeLockFlags, FlakeLockMode};
|
||||||
pub use flake_settings::FlakeSettings;
|
pub use flake_settings::FlakeSettings;
|
||||||
pub use flakeref::FlakeRef;
|
use flakeref::FlakeRef;
|
||||||
pub use flakeref_builder::FlakeRefBuilder;
|
use flakeref_parse_flags::FlakeRefParseFlags;
|
||||||
pub use flakeref_parse_flags::FlakeRefParseFlags;
|
|
||||||
pub use locked_flake::LockedFlake;
|
pub use locked_flake::LockedFlake;
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,6 @@ pub use version::NixVersion;
|
||||||
#[cfg(feature = "exprs")]
|
#[cfg(feature = "exprs")]
|
||||||
pub use expr::{EvalState, EvalStateBuilder, Value};
|
pub use expr::{EvalState, EvalStateBuilder, Value};
|
||||||
#[cfg(feature = "flakes")]
|
#[cfg(feature = "flakes")]
|
||||||
pub use flake::{FlakeRef, FlakeRefBuilder, FlakeSettings, LockedFlake};
|
pub use flake::{FlakeSettings, LockedFlake};
|
||||||
#[cfg(feature = "store")]
|
#[cfg(feature = "store")]
|
||||||
pub use store::{Store, StorePath};
|
pub use store::{Store, StorePath};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use std::ffi::CString;
|
use crate::errors::ErrorContext;
|
||||||
|
use crate::stdext::AsCPtr as _;
|
||||||
use crate::errors::{ErrorContext, ToNixideResult as _};
|
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::util::wrap;
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr as _;
|
use crate::util::wrappers::AsInnerPtr as _;
|
||||||
|
|
@ -70,10 +69,8 @@ impl ToString for LogFormat {
|
||||||
/// modified without nixide updating to account for this.
|
/// modified without nixide updating to account for this.
|
||||||
///
|
///
|
||||||
pub fn set_log_format(format: LogFormat) {
|
pub fn set_log_format(format: LogFormat) {
|
||||||
let c_format = CString::new(format.to_string()).to_nixide_result().unwrap();
|
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_set_log_format(ctx.as_ptr(), c_format.as_ptr());
|
sys::nix_set_log_format(ctx.as_ptr(), format.to_string().as_c_ptr().unwrap());
|
||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,21 @@
|
||||||
use std::ffi::{CString, c_void};
|
use std::ffi::c_void;
|
||||||
|
|
||||||
use crate::NixideResult;
|
use crate::NixideResult;
|
||||||
use crate::errors::{ErrorContext, ToNixideResult as _};
|
use crate::errors::ErrorContext;
|
||||||
|
use crate::stdext::AsCPtr as _;
|
||||||
use crate::util::wrap;
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr as _;
|
use crate::util::wrappers::AsInnerPtr as _;
|
||||||
|
|
||||||
// DEBUG: should this really be unsafe?
|
|
||||||
/// # Note
|
/// # Note
|
||||||
/// This function is intentionally marked unsafe to discourage its use.
|
/// This function is intentionally marked unsafe to discourage its use.
|
||||||
/// Please prefer [nixide::FlakeSettings] and [nixide::FetchersSettings].
|
/// Please prefer [nixide::FlakeSettings] and [nixide::FetchersSettings].
|
||||||
///
|
///
|
||||||
pub unsafe fn get_global_setting(key: &str) -> NixideResult<String> {
|
pub unsafe fn get_global_setting<S: AsRef<str>>(key: S) -> NixideResult<String> {
|
||||||
let c_key = CString::new(key).to_nixide_result()?;
|
let key = key.as_c_ptr()?;
|
||||||
|
|
||||||
wrap::nix_string_callback!(
|
wrap::nix_string_callback!(
|
||||||
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
|callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_setting_get(
|
sys::nix_setting_get(ctx.as_ptr(), key, Some(callback), userdata as *mut c_void);
|
||||||
ctx.as_ptr(),
|
|
||||||
c_key.as_ptr(),
|
|
||||||
Some(callback),
|
|
||||||
userdata as *mut c_void,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -29,11 +24,14 @@ pub unsafe fn get_global_setting(key: &str) -> NixideResult<String> {
|
||||||
/// This function is intentionally marked unsafe to discourage its use.
|
/// This function is intentionally marked unsafe to discourage its use.
|
||||||
/// Please prefer [nixide::FlakeSettings] and [nixide::FetchersSettings].
|
/// Please prefer [nixide::FlakeSettings] and [nixide::FetchersSettings].
|
||||||
///
|
///
|
||||||
pub unsafe fn set_global_setting(key: &str, value: &str) -> NixideResult<()> {
|
pub unsafe fn set_global_setting<S: AsRef<str>, T: AsRef<str>>(
|
||||||
let c_key = CString::new(key).to_nixide_result()?;
|
key: S,
|
||||||
let c_value = CString::new(value).to_nixide_result()?;
|
value: T,
|
||||||
|
) -> NixideResult<()> {
|
||||||
|
let key = key.as_c_ptr()?;
|
||||||
|
let value = value.as_c_ptr()?;
|
||||||
|
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_setting_set(ctx.as_ptr(), c_key.as_ptr(), c_value.as_ptr());
|
sys::nix_setting_set(ctx.as_ptr(), key, value);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use std::ffi::CString;
|
|
||||||
|
|
||||||
use crate::NixideResult;
|
use crate::NixideResult;
|
||||||
use crate::errors::{ErrorContext, ToNixideResult as _};
|
use crate::errors::ErrorContext;
|
||||||
|
use crate::stdext::AsCPtr as _;
|
||||||
use crate::util::wrap;
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr as _;
|
use crate::util::wrappers::AsInnerPtr as _;
|
||||||
|
|
||||||
|
|
@ -12,8 +11,8 @@ pub fn load_plugins() -> NixideResult<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_plugin<S: AsRef<str>>(path: S) -> NixideResult<()> {
|
pub fn register_plugin<S: AsRef<str>>(path: S) -> NixideResult<()> {
|
||||||
let c_path = CString::new(path.as_ref()).to_nixide_result()?;
|
let path_ptr = path.as_ref().into_c_ptr()?;
|
||||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||||
sys::nix_register_plugin(ctx.as_ptr(), c_path.as_ptr().cast_mut());
|
sys::nix_register_plugin(ctx.as_ptr(), path_ptr);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,33 @@ use std::str::from_utf8;
|
||||||
use crate::NixideResult;
|
use crate::NixideResult;
|
||||||
use crate::errors::new_nixide_error;
|
use crate::errors::new_nixide_error;
|
||||||
|
|
||||||
|
pub trait AsCPtr<T> {
|
||||||
|
#[allow(unused)]
|
||||||
|
fn as_c_ptr(&self) -> NixideResult<*const T>;
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
fn into_c_ptr(self) -> NixideResult<*mut T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> AsCPtr<c_char> for T
|
||||||
|
where
|
||||||
|
T: AsRef<str>,
|
||||||
|
{
|
||||||
|
fn as_c_ptr(&self) -> NixideResult<*const c_char> {
|
||||||
|
match CStr::from_bytes_until_nul(self.as_ref().as_bytes()) {
|
||||||
|
Ok(s) => Ok(s.as_ptr()),
|
||||||
|
Err(_) => Err(new_nixide_error!(StringNulByte)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_c_ptr(self) -> NixideResult<*mut c_char> {
|
||||||
|
match CStr::from_bytes_until_nul(self.as_ref().as_bytes()) {
|
||||||
|
Ok(s) => Ok(s.as_ptr().cast_mut()),
|
||||||
|
Err(_) => Err(new_nixide_error!(StringNulByte)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait CCharPtrExt {
|
pub trait CCharPtrExt {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn to_utf8_string(self) -> NixideResult<String>;
|
fn to_utf8_string(self) -> NixideResult<String>;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
mod cchar_ptr;
|
mod cchar_ptr;
|
||||||
mod slice;
|
mod slice;
|
||||||
|
|
||||||
pub(crate) use cchar_ptr::CCharPtrExt;
|
pub(crate) use cchar_ptr::{AsCPtr, CCharPtrExt};
|
||||||
pub(crate) use slice::SliceExt;
|
pub(crate) use slice::SliceExt;
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,14 @@ mod path;
|
||||||
pub use path::*;
|
pub use path::*;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ffi::{CString, 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 std::rc::Rc;
|
||||||
|
|
||||||
use crate::NixideResult;
|
use crate::NixideResult;
|
||||||
use crate::errors::{ErrorContext, ToNixideResult as _};
|
use crate::errors::ErrorContext;
|
||||||
|
use crate::stdext::AsCPtr as _;
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
use crate::util::wrap;
|
use crate::util::wrap;
|
||||||
use crate::util::wrappers::AsInnerPtr;
|
use crate::util::wrappers::AsInnerPtr;
|
||||||
|
|
@ -57,8 +58,7 @@ 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<Rc<RefCell<Self>>> {
|
pub fn open(uri: &str) -> NixideResult<Rc<RefCell<Self>>> {
|
||||||
let c_uri = CString::new(uri).to_nixide_result()?;
|
unsafe { Self::open_ptr(uri.as_c_ptr()?) }
|
||||||
unsafe { Self::open_ptr(c_uri.as_ptr()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens a connection to the default Nix store.
|
/// Opens a connection to the default Nix store.
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,8 @@ impl StorePath {
|
||||||
/// use nixide::{Store, StorePath};
|
/// use nixide::{Store, StorePath};
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let storeref = Store::default().unwrap();
|
/// let store_ref = Store::default().unwrap();
|
||||||
/// let path = StorePath::new(storeref, "/nix/store/f7gmvzd74wc1vlxzjdqy0af2381g8wr6-nix-manual-2.31.2-man").unwrap();
|
/// let path = StorePath::new("/nix/store/f7gmvzd74wc1vlxzjdqy0af2381g8wr6-nix-manual-2.31.2-man").unwrap();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue