nixide/nixide/src/flake/flake_reference.rs

100 lines
3 KiB
Rust
Raw Normal View History

2026-03-30 12:48:43 +10:00
use std::ffi::c_void;
2026-03-21 10:26:27 +10:00
use std::os::raw::c_char;
2026-03-30 12:48:43 +10:00
use std::ptr::{NonNull, null_mut};
2026-03-21 10:26:27 +10:00
use super::{FetchersSettings, FlakeReferenceParseFlags, FlakeSettings};
2026-03-30 12:48:43 +10:00
use crate::NixideError;
use crate::errors::{ErrorContext, new_nixide_error};
2026-03-21 10:26:27 +10:00
use crate::sys;
2026-03-30 12:48:43 +10:00
use crate::util::wrap;
2026-03-21 10:26:27 +10:00
use crate::util::wrappers::AsInnerPtr;
2026-03-30 12:48:43 +10:00
// XXX: TODO: rename FlakeReference -> FlakeRef
2026-03-19 00:39:44 +10:00
pub struct FlakeReference {
2026-03-30 12:48:43 +10:00
inner: NonNull<sys::nix_flake_reference>,
fragment: String,
2026-03-19 00:39:44 +10:00
}
2026-03-21 10:26:27 +10:00
2026-03-30 12:48:43 +10:00
// 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(),
// }
// }
// }
2026-03-19 00:39:44 +10:00
impl Drop for FlakeReference {
fn drop(&mut self) {
unsafe {
2026-03-30 12:48:43 +10:00
sys::nix_flake_reference_free(self.as_ptr());
2026-03-19 00:39:44 +10:00
}
}
}
2026-03-21 10:26:27 +10:00
2026-03-30 12:48:43 +10:00
impl AsInnerPtr<sys::nix_flake_reference> for FlakeReference {
#[inline]
unsafe fn as_ptr(&self) -> *mut sys::nix_flake_reference {
self.inner.as_ptr()
}
#[inline]
unsafe fn as_ref(&self) -> &sys::nix_flake_reference {
unsafe { self.inner.as_ref() }
2026-03-21 10:26:27 +10:00
}
2026-03-30 12:48:43 +10:00
#[inline]
unsafe fn as_mut(&mut self) -> &mut sys::nix_flake_reference {
unsafe { self.inner.as_mut() }
}
}
impl FlakeReference {
2026-03-19 00:39:44 +10:00
/// 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.
2026-03-30 12:48:43 +10:00
pub fn parse(
2026-03-19 00:39:44 +10:00
fetch_settings: &FetchersSettings,
flake_settings: &FlakeSettings,
flags: &FlakeReferenceParseFlags,
reference: &str,
2026-03-30 12:48:43 +10:00
) -> Result<FlakeReference, NixideError> {
2026-03-21 10:26:27 +10:00
let mut ptr: *mut sys::nix_flake_reference = null_mut();
2026-03-30 12:48:43 +10:00
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(),
flags.as_ptr(),
reference.as_ptr() as *const c_char,
reference.len(),
&mut ptr,
Some(callback),
userdata as *mut c_void,
)
}
)?;
2026-03-21 10:26:27 +10:00
match NonNull::new(ptr) {
2026-03-30 12:48:43 +10:00
Some(inner) => Ok(FlakeReference { inner, fragment }),
2026-03-21 10:26:27 +10:00
None => Err(new_nixide_error!(NullPtr)),
}
2026-03-19 00:39:44 +10:00
}
2026-03-30 12:48:43 +10:00
// 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
}
2026-03-19 00:39:44 +10:00
}