diff --git a/nixide/src/expr/eval_state_builder.rs b/nixide/src/expr/eval_state_builder.rs index f1a09e6..117cf8a 100644 --- a/nixide/src/expr/eval_state_builder.rs +++ b/nixide/src/expr/eval_state_builder.rs @@ -77,7 +77,6 @@ impl EvalStateBuilder { } // XXX: TODO: use `flakes()` instead - #[deprecated] #[cfg(feature = "flakes")] pub fn set_flake_settings(self, settings: &FlakeSettings) -> NixideResult { wrap::nix_fn!(|ctx: &ErrorContext| unsafe { @@ -93,7 +92,6 @@ impl EvalStateBuilder { #[cfg(feature = "flakes")] pub fn flakes(self) -> NixideResult { - #[allow(deprecated)] self.set_flake_settings(&FlakeSettings::new()?) } diff --git a/nixide/src/flake/flake_lock_flags.rs b/nixide/src/flake/flake_lock_flags.rs index d471987..06f3554 100644 --- a/nixide/src/flake/flake_lock_flags.rs +++ b/nixide/src/flake/flake_lock_flags.rs @@ -1,6 +1,6 @@ use std::ptr::NonNull; -use super::{FlakeReference, FlakeSettings}; +use super::{FlakeRef, FlakeSettings}; use crate::NixideResult; use crate::errors::ErrorContext; use crate::stdext::AsCPtr as _; @@ -67,7 +67,6 @@ impl AsInnerPtr for FlakeLockFlags { } impl FlakeLockFlags { - // XXX: TODO: what is the default FlakeLockMode? pub fn new(settings: &FlakeSettings) -> NixideResult { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { sys::nix_flake_lock_flags_new(ctx.as_ptr(), settings.as_ptr()) @@ -76,7 +75,7 @@ impl FlakeLockFlags { Ok(FlakeLockFlags { inner }) } - pub fn set_mode(&mut self, mode: &FlakeLockMode) -> NixideResult<()> { + pub fn set_mode(self, mode: FlakeLockMode) -> NixideResult { wrap::nix_fn!(|ctx: &ErrorContext| { match mode { FlakeLockMode::WriteAsNeeded => unsafe { @@ -89,7 +88,9 @@ 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. @@ -104,7 +105,7 @@ impl FlakeLockFlags { /// /// * `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: &FlakeReference) -> NixideResult<()> { + pub fn override_input(&mut self, path: &str, flakeref: &FlakeRef) -> NixideResult<()> { let input_path = path.as_c_ptr()?; wrap::nix_fn!(|ctx: &ErrorContext| unsafe { diff --git a/nixide/src/flake/flake_reference.rs b/nixide/src/flake/flake_reference.rs index 9b4e619..bfe44c5 100644 --- a/nixide/src/flake/flake_reference.rs +++ b/nixide/src/flake/flake_reference.rs @@ -1,17 +1,19 @@ use std::ffi::{c_char, c_void}; use std::ptr::{NonNull, null_mut}; -use super::{FetchersSettings, FlakeReferenceParseFlags, FlakeSettings}; +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; -// XXX: TODO: rename FlakeReference -> FlakeRef -pub struct FlakeReference { +pub struct FlakeRef { inner: NonNull, fragment: String, + + fetch_settings: FetchersSettings, + flake_settings: FlakeSettings, } // impl Clone for FlakeReference { @@ -28,7 +30,7 @@ pub struct FlakeReference { // } // } -impl Drop for FlakeReference { +impl Drop for FlakeRef { fn drop(&mut self) { unsafe { sys::nix_flake_reference_free(self.as_ptr()); @@ -36,7 +38,7 @@ impl Drop for FlakeReference { } } -impl AsInnerPtr for FlakeReference { +impl AsInnerPtr for FlakeRef { #[inline] unsafe fn as_ptr(&self) -> *mut sys::NixFlakeReference { self.inner.as_ptr() @@ -53,17 +55,16 @@ impl AsInnerPtr for FlakeReference { } } -impl FlakeReference { +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( - fetch_settings: &FetchersSettings, - flake_settings: &FlakeSettings, - flags: &FlakeReferenceParseFlags, - reference: &str, - ) -> Result { + pub fn parse>(reference: S) -> Result { + 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 { @@ -71,9 +72,9 @@ impl FlakeReference { ctx.as_ptr(), fetch_settings.as_ptr(), flake_settings.as_ptr(), - flags.as_ptr(), - reference.as_ptr() as *const c_char, - reference.len(), + 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, @@ -82,7 +83,12 @@ impl FlakeReference { )?; match NonNull::new(ptr) { - Some(inner) => Ok(FlakeReference { inner, fragment }), + Some(inner) => Ok(FlakeRef { + inner, + fragment, + fetch_settings, + flake_settings, + }), None => Err(new_nixide_error!(NullPtr)), } } diff --git a/nixide/src/flake/flake_reference_parse_flags.rs b/nixide/src/flake/flake_reference_parse_flags.rs index 758023a..f3bec84 100644 --- a/nixide/src/flake/flake_reference_parse_flags.rs +++ b/nixide/src/flake/flake_reference_parse_flags.rs @@ -10,7 +10,7 @@ use crate::util::wrappers::AsInnerPtr; /// Parameters for parsing a flake reference. #[derive(Debug)] -pub struct FlakeReferenceParseFlags { +pub struct FlakeRefParseFlags { inner: NonNull, } @@ -27,7 +27,7 @@ pub struct FlakeReferenceParseFlags { // } // } -impl Drop for FlakeReferenceParseFlags { +impl Drop for FlakeRefParseFlags { fn drop(&mut self) { unsafe { sys::nix_flake_reference_parse_flags_free(self.inner.as_ptr()); @@ -35,7 +35,7 @@ impl Drop for FlakeReferenceParseFlags { } } -impl AsInnerPtr for FlakeReferenceParseFlags { +impl AsInnerPtr for FlakeRefParseFlags { #[inline] unsafe fn as_ptr(&self) -> *mut sys::NixFlakeReferenceParseFlags { self.inner.as_ptr() @@ -52,7 +52,7 @@ impl AsInnerPtr for FlakeReferenceParseFlags { } } -impl FlakeReferenceParseFlags { +impl FlakeRefParseFlags { pub fn new(settings: &FlakeSettings) -> NixideResult { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { sys::nix_flake_reference_parse_flags_new(ctx.as_ptr(), settings.as_ptr()) diff --git a/nixide/src/flake/locked_flake.rs b/nixide/src/flake/locked_flake.rs index 4192b8f..3a76880 100644 --- a/nixide/src/flake/locked_flake.rs +++ b/nixide/src/flake/locked_flake.rs @@ -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::ptr::NonNull; +use std::rc::Rc; -use super::{FetchersSettings, FlakeLockFlags, FlakeReference, FlakeSettings}; +use super::{FetchersSettings, FlakeLockFlags, FlakeLockMode, FlakeRef, FlakeSettings}; use crate::errors::ErrorContext; use crate::sys; use crate::util::wrap; @@ -12,31 +14,13 @@ use crate::{EvalState, NixideResult, Value}; pub struct LockedFlake { inner: NonNull, - flakeref: FlakeReference, - state: EvalState, - flags: FlakeLockFlags, + flakeref: FlakeRef, + state: Rc>>, + lock_flags: FlakeLockFlags, fetch_settings: FetchersSettings, flake_settings: FlakeSettings, } -// impl Clone for LockedFlake { -// 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(), -// flakeref: self.flakeref.clone(), -// state: self.state.clone(), -// flags: self.flags.clone(), -// fetch_settings: self.fetch_settings.clone(), -// flake_settings: self.flake_settings.clone(), -// } -// } -// } - impl Drop for LockedFlake { fn drop(&mut self) { unsafe { @@ -64,30 +48,33 @@ impl AsInnerPtr for LockedFlake { impl LockedFlake { pub fn lock( - fetch_settings: &FetchersSettings, - flake_settings: &FlakeSettings, + mode: FlakeLockMode, + flakeref: FlakeRef, state: &EvalState, - flags: &FlakeLockFlags, - flakeref: &FlakeReference, ) -> NixideResult { + let state_inner = state.inner_ref(); + let fetch_settings = FetchersSettings::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 { sys::nix_flake_lock( ctx.as_ptr(), fetch_settings.as_ptr(), flake_settings.as_ptr(), - state.as_ptr(), - flags.as_ptr(), + state_inner.borrow().as_ptr(), + lock_flags.as_ptr(), flakeref.as_ptr(), ) })?; Ok(Self { inner, - flakeref: flakeref.clone(), - state: state.clone(), - flags: flags.clone(), - fetch_settings: fetch_settings.clone(), - flake_settings: flake_settings.clone(), + flakeref, + state: state_inner.clone(), + lock_flags, + fetch_settings, + flake_settings, }) } @@ -97,12 +84,12 @@ impl LockedFlake { sys::nix_locked_flake_get_output_attrs( ctx.as_ptr(), self.flake_settings.as_ptr(), - self.state.as_ptr(), + self.state.borrow().as_ptr(), self.inner.as_ptr(), ) })?; - Ok(Value::from((value, &self.state))) + Ok(Value::from((value, self.state.clone()))) } } @@ -111,8 +98,8 @@ mod tests { use std::fs; use std::sync::Once; - use super::{FetchersSettings, FlakeLockFlags, FlakeReference, FlakeSettings, LockedFlake}; - use crate::flake::{FlakeLockMode, FlakeReferenceParseFlags}; + use super::{FetchersSettings, FlakeLockFlags, FlakeRef, FlakeSettings, LockedFlake}; + use crate::flake::{FlakeLockMode, FlakeRefParseFlags}; use crate::{EvalStateBuilder, Store, Value, set_global_setting}; static INIT: Once = Once::new(); @@ -167,36 +154,19 @@ mod tests { let store_ref = Store::default().unwrap(); let flake_settings = FlakeSettings::new().unwrap(); - let mut eval_state = EvalStateBuilder::new(store_ref.clone()) + let eval_state = EvalStateBuilder::new(store_ref.clone()) .unwrap() .set_flake_settings(&flake_settings) .unwrap() .build() .unwrap(); - let fetchers_settings = FetchersSettings::new().unwrap(); - let flake_lock_flags = FlakeLockFlags::new(&flake_settings).unwrap(); - - let flakeref = FlakeReference::parse( - &fetchers_settings, - &flake_settings, - &FlakeReferenceParseFlags::new(&flake_settings).unwrap(), - &format!("path:{}#subthing", tmp_dir.path().display()), - ) - .unwrap(); + let flakeref = + FlakeRef::parse(&format!("path:{}#subthing", tmp_dir.path().display())).unwrap(); assert_eq!(flakeref.fragment(), "subthing"); - let locked_flake = LockedFlake::lock( - &fetchers_settings, - &flake_settings, - &eval_state, - &flake_lock_flags, - &flakeref, - ) - .unwrap(); - - let outputs = locked_flake.outputs().unwrap(); + let outputs = LockedFlake::lock(, flakeref, &eval_state).unwrap().outputs().unwrap(); assert!(matches!(outputs, Value::Attrs(_))); if let Value::Attrs(outputs) = outputs { @@ -216,7 +186,7 @@ mod tests { let store_ref = Store::default().unwrap(); let fetchers_settings = FetchersSettings::new().unwrap(); let flake_settings = FlakeSettings::new().unwrap(); - let mut eval_state = EvalStateBuilder::new(store_ref.clone()) + let eval_state = EvalStateBuilder::new(store_ref.clone()) .unwrap() .set_flake_settings(&flake_settings) .unwrap() @@ -281,33 +251,20 @@ mod tests { let mut flake_lock_flags = FlakeLockFlags::new(&flake_settings).unwrap(); - let mut flake_reference_parse_flags = - FlakeReferenceParseFlags::new(&flake_settings).unwrap(); + let mut flake_reference_parse_flags = FlakeRefParseFlags::new(&flake_settings).unwrap(); flake_reference_parse_flags .set_base_directory(tmp_dir.path().to_str().unwrap()) .unwrap(); - let flakeref_a = FlakeReference::parse( - &fetchers_settings, - &flake_settings, - &flake_reference_parse_flags, - &format!("path:{}", &flake_dir_a_str), - ) - .unwrap(); + let flakeref_a = FlakeRef::parse(&format!("path:{}", &flake_dir_a_str)).unwrap(); assert_eq!(flakeref_a.fragment(), ""); // Step 1: Do not update (check), fails flake_lock_flags.set_mode(&FlakeLockMode::Check).unwrap(); - let locked_flake = LockedFlake::lock( - &fetchers_settings, - &flake_settings, - &eval_state, - &flake_lock_flags, - &flakeref_a, - ); + let locked_flake = LockedFlake::lock(flake_lock_flags, 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 { @@ -318,14 +275,7 @@ mod tests { // Step 2: Update but do not write, succeeds flake_lock_flags.set_mode(&FlakeLockMode::Virtual).unwrap(); - let locked_flake = LockedFlake::lock( - &fetchers_settings, - &flake_settings, - &eval_state, - &flake_lock_flags, - &flakeref_a, - ) - .unwrap(); + let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap(); let outputs = locked_flake.outputs().unwrap(); @@ -342,13 +292,7 @@ mod tests { // Step 3: The lock was not written, so Step 1 would fail again flake_lock_flags.set_mode(&FlakeLockMode::Check).unwrap(); - let locked_flake = LockedFlake::lock( - &fetchers_settings, - &flake_settings, - &eval_state, - &flake_lock_flags, - &flakeref_a, - ); + 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"), @@ -362,14 +306,7 @@ mod tests { .set_mode(&FlakeLockMode::WriteAsNeeded) .unwrap(); - let locked_flake = LockedFlake::lock( - &fetchers_settings, - &flake_settings, - &eval_state, - &flake_lock_flags, - &flakeref_a, - ) - .unwrap(); + let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap(); let outputs = locked_flake.outputs().unwrap(); @@ -386,14 +323,7 @@ mod tests { // Step 5: Lock was written, so Step 1 succeeds flake_lock_flags.set_mode(&FlakeLockMode::Check).unwrap(); - let locked_flake = LockedFlake::lock( - &fetchers_settings, - &flake_settings, - &eval_state, - &flake_lock_flags, - &flakeref_a, - ) - .unwrap(); + let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap(); let outputs = locked_flake.outputs().unwrap(); @@ -414,25 +344,12 @@ mod tests { .set_mode(&FlakeLockMode::WriteAsNeeded) .unwrap(); - let flakeref_c = FlakeReference::parse( - &fetchers_settings, - &flake_settings, - &flake_reference_parse_flags, - &format!("path:{}", &flake_dir_c_str), - ) - .unwrap(); + let flakeref_c = FlakeRef::parse(&format!("path:{}", &flake_dir_c_str)).unwrap(); assert_eq!(flakeref_c.fragment(), ""); flake_lock_flags.override_input("b", &flakeref_c).unwrap(); - let locked_flake = LockedFlake::lock( - &fetchers_settings, - &flake_settings, - &eval_state, - &flake_lock_flags, - &flakeref_a, - ) - .unwrap(); + let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap(); let outputs = locked_flake.outputs().unwrap(); @@ -452,14 +369,7 @@ mod tests { // Step 7: Override was not written; lock still points to b flake_lock_flags.set_mode(&FlakeLockMode::Check).unwrap(); - let locked_flake = LockedFlake::lock( - &fetchers_settings, - &flake_settings, - &eval_state, - &flake_lock_flags, - &flakeref_a, - ) - .unwrap(); + let locked_flake = LockedFlake::lock(flake_lock_flags, flakeref_a, &eval_state).unwrap(); let outputs = locked_flake.outputs().unwrap(); diff --git a/nixide/src/flake/mod.rs b/nixide/src/flake/mod.rs index 314173e..53f858c 100644 --- a/nixide/src/flake/mod.rs +++ b/nixide/src/flake/mod.rs @@ -7,7 +7,7 @@ mod locked_flake; use fetchers_settings::FetchersSettings; use flake_lock_flags::{FlakeLockFlags, FlakeLockMode}; -use flake_reference::FlakeReference; -use flake_reference_parse_flags::FlakeReferenceParseFlags; +use flake_reference::FlakeRef; +use flake_reference_parse_flags::FlakeRefParseFlags; pub use flake_settings::FlakeSettings; pub use locked_flake::LockedFlake;