diff --git a/flake.lock b/flake.lock index e9d0a34..65e4ad9 100644 --- a/flake.lock +++ b/flake.lock @@ -161,15 +161,16 @@ "nixpkgs-regression": "nixpkgs-regression" }, "locked": { - "lastModified": 1762723967, - "narHash": "sha256-QrkPq3v5Px8rdl4+FoONC8FwiIw48Jrgk4cbucbyhyw=", + "lastModified": 1763665175, + "narHash": "sha256-BRplTcyC4Y9TGNAKTRxGfwFINBkEHpFyZbfe3zIDh64=", "owner": "DeterminateSystems", "repo": "nix-src", - "rev": "42a402fc873de408a4c00017b134759093be2d8c", + "rev": "922ee5678891447daddaa5885bc671ef806fc715", "type": "github" }, "original": { "owner": "DeterminateSystems", + "ref": "RossComputerGuy/capi-derived-path", "repo": "nix-src", "type": "github" } diff --git a/flake.nix b/flake.nix index 5aac86b..c1bbf83 100644 --- a/flake.nix +++ b/flake.nix @@ -3,7 +3,7 @@ inputs = { flake-parts.url = "github:hercules-ci/flake-parts"; - nix.url = "github:DeterminateSystems/nix-src"; + nix.url = "github:DeterminateSystems/nix-src/RossComputerGuy/capi-derived-path"; nix.inputs.nixpkgs.follows = "nixpkgs"; nix-cargo-integration.url = "github:yusdacra/nix-cargo-integration"; nix-cargo-integration.inputs.nixpkgs.follows = "nixpkgs"; diff --git a/nix-bindings-store/src/derived_path.rs b/nix-bindings-store/src/derived_path.rs new file mode 100644 index 0000000..bc1f749 --- /dev/null +++ b/nix-bindings-store/src/derived_path.rs @@ -0,0 +1,71 @@ +use std::ptr::NonNull; + +use super::path::StorePath; + +use anyhow::Result; +use nix_bindings_bindgen_raw as raw; +use nix_bindings_util::context::Context; +use nix_bindings_util::{check_call, result_string_init}; + +pub struct DerivedPath { + raw: NonNull, +} +impl DerivedPath { + pub fn get_store_path(&self) -> Result { + let mut context = Context::new(); + unsafe { + let store_path = check_call!(raw::derived_path_get_store_path( + &mut context, + self.as_ptr() + ))?; + let store_path = + NonNull::new(store_path).expect("nix_derived_path_get_store_path returned a null pointer"); + Ok(StorePath::new_raw(store_path)) + } + } + + /// This is a low level function that you shouldn't have to call unless you are developing the Nix bindings. + /// + /// Construct a new `DerivedPath` by first cloning the C derived path. + /// + /// # Safety + /// + /// This does not take ownership of the C derived path, so it should be a borrowed pointer, or you should free it. + pub unsafe fn new_raw_clone(raw: NonNull) -> Self { + Self::new_raw( + NonNull::new(raw::derived_path_clone(raw.as_ptr())) + .or_else(|| panic!("nix_derived_path_clone returned a null pointer")) + .unwrap(), + ) + } + + /// This is a low level function that you shouldn't have to call unless you are developing the Nix bindings. + /// + /// Takes ownership of a C `nix_derived_path`. It will be freed when the `DerivedPath` is dropped. + /// + /// # Safety + /// + /// The caller must ensure that the provided `NonNull` is valid and that the ownership + /// semantics are correctly followed. The `raw` pointer must not be used after being passed to this function. + pub unsafe fn new_raw(raw: NonNull) -> Self { + DerivedPath { raw } + } + + /// This is a low level function that you shouldn't have to call unless you are developing the Nix bindings. + /// + /// Get a pointer to the underlying Nix C API derived path. + /// + /// # Safety + /// + /// This function is unsafe because it returns a raw pointer. The caller must ensure that the pointer is not used beyond the lifetime of this `DerivedPath`. + pub unsafe fn as_ptr(&self) -> *mut raw::DerivedPath { + self.raw.as_ptr() + } +} +impl Drop for DerivedPath { + fn drop(&mut self) { + unsafe { + raw::derived_path_free(self.as_ptr()); + } + } +} diff --git a/nix-bindings-store/src/lib.rs b/nix-bindings-store/src/lib.rs index 6010f2e..9b6b3da 100644 --- a/nix-bindings-store/src/lib.rs +++ b/nix-bindings-store/src/lib.rs @@ -1,3 +1,4 @@ pub mod derivation; +pub mod derived_path; pub mod path; pub mod store;