2025-04-02 18:49:03 +02:00
pub mod __private ;
2024-03-19 14:43:01 +01:00
use nix_c_raw as raw ;
2024-06-15 14:51:26 +02:00
use nix_util ::{ check_call , context ::Context } ;
2024-05-09 12:41:34 -04:00
use std ::ptr ::{ null_mut , NonNull } ;
2024-03-19 14:43:01 +01:00
// TODO: test: cloning a thunk does not duplicate the evaluation.
2024-04-09 13:13:52 +02:00
pub type Int = i64 ;
2024-05-24 11:15:43 +02:00
/// The type of a value (or thunk)
2024-04-04 16:38:12 +02:00
#[ derive(Eq, PartialEq, Debug) ]
2024-03-19 14:43:01 +01:00
pub enum ValueType {
AttrSet ,
Bool ,
External ,
Float ,
Function ,
Int ,
List ,
Null ,
Path ,
String ,
Unknown ,
}
2024-06-14 18:42:23 +02:00
impl ValueType {
/// Convert a raw value type to a `ValueType`.
///
/// Return `None` if the Value is still a thunk (i.e. not yet evaluated).
///
/// Return `Some(ValueType::Unknown)` if the value type is not recognized.
pub ( crate ) fn from_raw ( raw : raw ::ValueType ) -> Option < ValueType > {
2024-03-19 14:43:01 +01:00
match raw {
2024-06-14 18:42:23 +02:00
raw ::ValueType_NIX_TYPE_ATTRS = > Some ( ValueType ::AttrSet ) ,
raw ::ValueType_NIX_TYPE_BOOL = > Some ( ValueType ::Bool ) ,
raw ::ValueType_NIX_TYPE_EXTERNAL = > Some ( ValueType ::External ) ,
raw ::ValueType_NIX_TYPE_FLOAT = > Some ( ValueType ::Float ) ,
raw ::ValueType_NIX_TYPE_FUNCTION = > Some ( ValueType ::Function ) ,
raw ::ValueType_NIX_TYPE_INT = > Some ( ValueType ::Int ) ,
raw ::ValueType_NIX_TYPE_LIST = > Some ( ValueType ::List ) ,
raw ::ValueType_NIX_TYPE_NULL = > Some ( ValueType ::Null ) ,
raw ::ValueType_NIX_TYPE_PATH = > Some ( ValueType ::Path ) ,
raw ::ValueType_NIX_TYPE_STRING = > Some ( ValueType ::String ) ,
raw ::ValueType_NIX_TYPE_THUNK = > None ,
2024-05-09 12:41:34 -04:00
// This would happen if a new type of value is added in Nix.
2024-06-14 18:42:23 +02:00
_ = > Some ( ValueType ::Unknown ) ,
2024-03-19 14:43:01 +01:00
}
}
}
/* A pointer to a value or thunk, to be used with EvalState methods. */
pub struct Value {
inner : NonNull < raw ::Value > ,
}
impl Value {
2024-05-24 09:09:41 +02:00
/// Take ownership of a new Value.
///
/// This does not call `nix_gc_incref`, but does call `nix_gc_decref` when dropped.
2024-12-17 10:40:03 +01:00
///
/// # Safety
///
/// The caller must ensure that the provided `inner` has a positive reference count, and that `inner` is not used after the returned `Value` is dropped.
pub ( crate ) unsafe fn new ( inner : * mut raw ::Value ) -> Self {
2024-03-19 14:43:01 +01:00
Value {
inner : NonNull ::new ( inner ) . unwrap ( ) ,
}
}
2024-05-24 09:09:41 +02:00
/// Borrow a reference to a Value.
///
/// This calls `nix_gc_incref`, and the returned Value will call `nix_gc_decref` when dropped.
2024-12-17 10:40:03 +01:00
///
/// # Safety
///
/// The caller must ensure that the provided `inner` has a positive reference count.
pub ( crate ) unsafe fn new_borrowed ( inner : * mut raw ::Value ) -> Self {
2024-05-24 09:09:41 +02:00
let v = Value ::new ( inner ) ;
unsafe { raw ::value_incref ( null_mut ( ) , inner ) } ;
v
}
2024-12-17 10:40:03 +01:00
/// # Safety
///
/// The caller must ensure that the returned pointer is not used after the `Value` is dropped.
pub ( crate ) unsafe fn raw_ptr ( & self ) -> * mut raw ::Value {
2024-03-19 14:43:01 +01:00
self . inner . as_ptr ( )
}
}
impl Drop for Value {
fn drop ( & mut self ) {
unsafe {
2024-05-09 12:41:34 -04:00
// ignoring error because the only failure mode is leaking memory
2024-08-29 15:52:16 +02:00
raw ::value_decref ( null_mut ( ) , self . inner . as_ptr ( ) ) ;
2024-03-19 14:43:01 +01:00
}
}
}
impl Clone for Value {
fn clone ( & self ) -> Self {
2024-06-15 14:51:26 +02:00
// TODO: Is it worth allocating a new Context here? Ideally cloning is cheap.
// this is very unlikely to error, and it is not recoverable
// Maybe try without, and try again with context to report details?
unsafe {
2024-08-29 15:52:16 +02:00
check_call! ( raw ::value_incref ( & mut Context ::new ( ) , self . inner . as_ptr ( ) ) ) . unwrap ( ) ;
2024-06-15 14:51:26 +02:00
}
2024-05-09 12:41:34 -04:00
// can't return an error here, but we don't want to ignore the error either as it means we could use-after-free
2024-03-19 14:43:01 +01:00
Value { inner : self . inner }
}
}
// Tested in eval_state.rs