refact: remove Thunk from ValueType and introduce ValueTypeOrThunk to address #30

(cherry picked from commit 97c05175b633b364686790549b11e43cfb2f1d2c)
This commit is contained in:
Philipp Zander 2024-06-03 04:18:58 +02:00 committed by Robert Hensing
parent d89fb1803f
commit 673f80e243
2 changed files with 38 additions and 28 deletions

View file

@ -1,4 +1,4 @@
use crate::value::{Int, Value, ValueType}; use crate::value::{Int, Value, ValueType, ValueTypeOrThunk};
use anyhow::Context as _; use anyhow::Context as _;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -133,19 +133,24 @@ impl EvalState {
} }
self.context.check_err() self.context.check_err()
} }
pub fn value_is_thunk(&self, value: &Value) -> bool { pub fn value_type_unforced(&self, value: &Value) -> ValueTypeOrThunk {
let r = unsafe {
raw::get_type(self.context.ptr(), value.raw_ptr()) == raw::ValueType_NIX_TYPE_THUNK
};
self.context.check_err().unwrap();
r
}
pub fn value_type(&self, value: &Value) -> Result<ValueType> {
if self.value_is_thunk(value) {
self.force(value)?;
}
let r = unsafe { raw::get_type(self.context.ptr(), value.raw_ptr()) }; let r = unsafe { raw::get_type(self.context.ptr(), value.raw_ptr()) };
Ok(ValueType::from_raw(r)) self.context.check_err().unwrap();
ValueTypeOrThunk::from_raw(r)
}
pub fn value_type_forced(&self, value: &Value) -> Result<ValueType> {
match self.value_type_unforced(value) {
ValueTypeOrThunk::ValueType(a) => Ok(a),
ValueTypeOrThunk::Thunk => {
self.force(value)?;
match self.value_type_unforced(value) {
ValueTypeOrThunk::ValueType(a) => Ok(a),
ValueTypeOrThunk::Thunk => {
panic!("values should not be thunks after having been forced.")
}
}
}
}
} }
pub fn require_int(&self, v: &Value) -> Result<Int> { pub fn require_int(&self, v: &Value) -> Result<Int> {
let t = self.value_type(v).unwrap(); let t = self.value_type(v).unwrap();

View file

@ -19,26 +19,31 @@ pub enum ValueType {
Null, Null,
Path, Path,
String, String,
Thunk,
Unknown, Unknown,
} }
impl ValueType { #[derive(Eq, PartialEq, Debug)]
pub(crate) fn from_raw(raw: raw::ValueType) -> ValueType { pub enum ValueTypeOrThunk {
ValueType(ValueType),
Thunk,
}
impl ValueTypeOrThunk {
pub(crate) fn from_raw(raw: raw::ValueType) -> ValueTypeOrThunk {
match raw { match raw {
raw::ValueType_NIX_TYPE_ATTRS => ValueType::AttrSet, raw::ValueType_NIX_TYPE_ATTRS => ValueTypeOrThunk::ValueType(ValueType::AttrSet),
raw::ValueType_NIX_TYPE_BOOL => ValueType::Bool, raw::ValueType_NIX_TYPE_BOOL => ValueTypeOrThunk::ValueType(ValueType::Bool),
raw::ValueType_NIX_TYPE_EXTERNAL => ValueType::External, raw::ValueType_NIX_TYPE_EXTERNAL => ValueTypeOrThunk::ValueType(ValueType::External),
raw::ValueType_NIX_TYPE_FLOAT => ValueType::Float, raw::ValueType_NIX_TYPE_FLOAT => ValueTypeOrThunk::ValueType(ValueType::Float),
raw::ValueType_NIX_TYPE_FUNCTION => ValueType::Function, raw::ValueType_NIX_TYPE_FUNCTION => ValueTypeOrThunk::ValueType(ValueType::Function),
raw::ValueType_NIX_TYPE_INT => ValueType::Int, raw::ValueType_NIX_TYPE_INT => ValueTypeOrThunk::ValueType(ValueType::Int),
raw::ValueType_NIX_TYPE_LIST => ValueType::List, raw::ValueType_NIX_TYPE_LIST => ValueTypeOrThunk::ValueType(ValueType::List),
raw::ValueType_NIX_TYPE_NULL => ValueType::Null, raw::ValueType_NIX_TYPE_NULL => ValueTypeOrThunk::ValueType(ValueType::Null),
raw::ValueType_NIX_TYPE_PATH => ValueType::Path, raw::ValueType_NIX_TYPE_PATH => ValueTypeOrThunk::ValueType(ValueType::Path),
raw::ValueType_NIX_TYPE_STRING => ValueType::String, raw::ValueType_NIX_TYPE_STRING => ValueTypeOrThunk::ValueType(ValueType::String),
raw::ValueType_NIX_TYPE_THUNK => ValueType::Thunk, raw::ValueType_NIX_TYPE_THUNK => ValueTypeOrThunk::Thunk,
// This would happen if a new type of value is added in Nix. // This would happen if a new type of value is added in Nix.
_ => ValueType::Unknown, _ => ValueTypeOrThunk::ValueType(ValueType::Unknown),
} }
} }
} }