begin nixide::expr refactor
This commit is contained in:
parent
bfb2010f19
commit
0ba06d0f2c
25 changed files with 681 additions and 254 deletions
|
|
@ -68,9 +68,20 @@ pub(crate) struct ErrorContext {
|
|||
}
|
||||
|
||||
impl AsInnerPtr<sys::nix_c_context> for ErrorContext {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::nix_c_context {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::nix_c_context {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::nix_c_context {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<NixideResult<()>> for &ErrorContext {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ use crate::errors::new_nixide_error;
|
|||
use super::Value;
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::sys;
|
||||
use crate::util::wrap;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
use crate::{NixideError, Store};
|
||||
use crate::{NixideResult, Store};
|
||||
|
||||
/// Nix evaluation state for evaluating expressions.
|
||||
///
|
||||
|
|
@ -18,14 +19,24 @@ pub struct EvalState {
|
|||
inner: NonNull<sys::EvalState>,
|
||||
|
||||
// XXX: TODO: is an `Arc<Store>` necessary or just a `Store`
|
||||
#[allow(dead_code)]
|
||||
store: Arc<Store>,
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::EvalState> for EvalState {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::EvalState {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::EvalState {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::EvalState {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl EvalState {
|
||||
|
|
@ -34,6 +45,11 @@ impl EvalState {
|
|||
Self { inner, store }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) unsafe fn store_ref(&self) -> &Store {
|
||||
self.store.as_ref()
|
||||
}
|
||||
|
||||
/// Evaluate a Nix expression from a string.
|
||||
///
|
||||
/// # Arguments
|
||||
|
|
@ -44,24 +60,15 @@ impl EvalState {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if evaluation fails.
|
||||
pub fn eval_from_string(&self, expr: &str, path: &str) -> Result<Value, NixideError> {
|
||||
pub fn eval_from_string(&self, expr: &str, path: &str) -> NixideResult<Value> {
|
||||
let expr_c = CString::new(expr).or(Err(new_nixide_error!(StringNulByte)))?;
|
||||
let path_c = CString::new(path).or(Err(new_nixide_error!(StringNulByte)))?;
|
||||
|
||||
let ctx = ErrorContext::new();
|
||||
// Allocate value for result
|
||||
// XXX: TODO: refactor this code to use `nixide::Value`
|
||||
let value_ptr = unsafe { sys::nix_alloc_value(ctx.as_ptr(), self.as_ptr()) };
|
||||
let value = match ctx.peak() {
|
||||
Some(err) => Err(err),
|
||||
None => match NonNull::new(value_ptr) {
|
||||
Some(inner) => Ok(Value { inner }),
|
||||
None => Err(new_nixide_error!(NullPtr)),
|
||||
},
|
||||
}?;
|
||||
let value = self.new_value()?;
|
||||
|
||||
// Evaluate expression
|
||||
unsafe {
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_expr_eval_from_string(
|
||||
ctx.as_ptr(),
|
||||
self.as_ptr(),
|
||||
|
|
@ -69,11 +76,8 @@ impl EvalState {
|
|||
path_c.as_ptr(),
|
||||
value.as_ptr(),
|
||||
);
|
||||
};
|
||||
match ctx.peak() {
|
||||
Some(err) => Err(err),
|
||||
None => Ok(value),
|
||||
}
|
||||
value
|
||||
})
|
||||
}
|
||||
|
||||
/// Allocate a new value.
|
||||
|
|
@ -81,16 +85,13 @@ impl EvalState {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if value allocation fails.
|
||||
pub fn alloc_value(&self) -> Result<Value, NixideError> {
|
||||
let ctx = ErrorContext::new();
|
||||
let value_ptr = unsafe { sys::nix_alloc_value(ctx.as_ptr(), self.as_ptr()) };
|
||||
match ctx.peak() {
|
||||
Some(err) => Err(err),
|
||||
None => match NonNull::new(value_ptr) {
|
||||
Some(inner) => Ok(Value { inner }),
|
||||
None => Err(new_nixide_error!(NullPtr)),
|
||||
},
|
||||
}
|
||||
pub(self) fn new_value(&self) -> NixideResult<Value> {
|
||||
// XXX: TODO: should this function be `Value::new` instead?
|
||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_alloc_value(ctx.as_ptr(), self.as_ptr())
|
||||
})?;
|
||||
|
||||
Ok(Value::new(inner, self))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ use std::ptr::NonNull;
|
|||
use std::sync::Arc;
|
||||
|
||||
use super::EvalState;
|
||||
use crate::errors::{new_nixide_error, ErrorContext, NixideError};
|
||||
use crate::errors::{ErrorContext, NixideResult};
|
||||
use crate::sys;
|
||||
use crate::util::wrap;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
use crate::Store;
|
||||
|
||||
|
|
@ -16,6 +17,23 @@ pub struct EvalStateBuilder {
|
|||
store: Arc<Store>,
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::nix_eval_state_builder> for EvalStateBuilder {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::nix_eval_state_builder {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::nix_eval_state_builder {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::nix_eval_state_builder {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl EvalStateBuilder {
|
||||
/// Create a new evaluation state builder.
|
||||
///
|
||||
|
|
@ -26,12 +44,10 @@ impl EvalStateBuilder {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the builder cannot be created.
|
||||
pub fn new(store: &Arc<Store>) -> Result<Self, NixideError> {
|
||||
// SAFETY: store context and store are valid
|
||||
let builder_ptr =
|
||||
unsafe { sys::nix_eval_state_builder_new(store._context.as_ptr(), store.as_ptr()) };
|
||||
|
||||
let inner = NonNull::new(builder_ptr).ok_or(new_nixide_error!(NullPtr))?;
|
||||
pub fn new(store: &Arc<Store>) -> NixideResult<Self> {
|
||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_eval_state_builder_new(ctx.as_ptr(), store.as_ptr())
|
||||
})?;
|
||||
|
||||
Ok(EvalStateBuilder {
|
||||
inner,
|
||||
|
|
@ -44,29 +60,19 @@ impl EvalStateBuilder {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the evaluation state cannot be built.
|
||||
pub fn build(self) -> Result<EvalState, NixideError> {
|
||||
let ctx = ErrorContext::new();
|
||||
pub fn build(self) -> NixideResult<EvalState> {
|
||||
// Load configuration first
|
||||
unsafe { sys::nix_eval_state_builder_load(ctx.as_ptr(), self.as_ptr()) };
|
||||
if let Some(err) = ctx.peak() {
|
||||
return Err(err);
|
||||
}
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_eval_state_builder_load(ctx.as_ptr(), self.as_ptr())
|
||||
})?;
|
||||
|
||||
// Build the state
|
||||
let state_ptr = unsafe { sys::nix_eval_state_build(ctx.as_ptr(), self.as_ptr()) };
|
||||
if let Some(err) = ctx.peak() {
|
||||
return Err(err);
|
||||
}
|
||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_eval_state_build(ctx.as_ptr(), self.as_ptr())
|
||||
})?;
|
||||
|
||||
let inner = NonNull::new(state_ptr).ok_or(new_nixide_error!(NullPtr))?;
|
||||
|
||||
// The builder is consumed here - its Drop will clean up
|
||||
Ok(EvalState::new(inner, self.store.clone()))
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn as_ptr(&self) -> *mut sys::nix_eval_state_builder {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EvalStateBuilder {
|
||||
|
|
|
|||
|
|
@ -3,10 +3,14 @@ mod tests;
|
|||
|
||||
mod evalstate;
|
||||
mod evalstatebuilder;
|
||||
mod realised_string;
|
||||
mod value;
|
||||
mod values;
|
||||
mod valuetype;
|
||||
|
||||
pub use evalstate::EvalState;
|
||||
pub use evalstatebuilder::EvalStateBuilder;
|
||||
pub use realised_string::RealisedString;
|
||||
pub use value::Value;
|
||||
pub use values::{NixInt, NixValue};
|
||||
pub use valuetype::ValueType;
|
||||
|
|
|
|||
121
nixide/src/expr/realised_string.rs
Normal file
121
nixide/src/expr/realised_string.rs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
use std::ffi::c_char;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::expr::values::NixString;
|
||||
use crate::stdext::CCharPtrExt;
|
||||
use crate::sys;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
use crate::util::LazyArray;
|
||||
use crate::util::{panic_issue_call_failed, wrap};
|
||||
use crate::{EvalState, NixideResult, StorePath};
|
||||
|
||||
pub struct RealisedString {
|
||||
inner: NonNull<sys::nix_realised_string>,
|
||||
// pub path: LazyCell<StorePath, Box<fn() -> StorePath>>,
|
||||
pub path: StorePath,
|
||||
pub children: LazyArray<StorePath, fn(&LazyArray<StorePath, fn(usize) -> StorePath>, usize) -> StorePath>>,
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::nix_realised_string> for RealisedString {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::nix_realised_string {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::nix_realised_string {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::nix_realised_string {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RealisedString {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
sys::nix_realised_string_free(self.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RealisedString {
|
||||
/// Realise a string context.
|
||||
///
|
||||
/// This will
|
||||
/// - realise the store paths referenced by the string's context, and
|
||||
/// - perform the replacement of placeholders.
|
||||
/// - create temporary garbage collection roots for the store paths, for
|
||||
/// the lifetime of the current process.
|
||||
/// - log to stderr
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * value - Nix value, which must be a string
|
||||
/// * state - Nix evaluator state
|
||||
/// * isIFD - If true, disallow derivation outputs if setting `allow-import-from-derivation` is false.
|
||||
/// You should set this to true when this call is part of a primop.
|
||||
/// You should set this to false when building for your application's purpose.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// NULL if failed, or a new nix_realised_string, which must be freed with nix_realised_string_free
|
||||
pub fn new(value: &NixString, state: &Arc<EvalState>) -> NixideResult<Self> {
|
||||
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_string_realise(
|
||||
ctx.as_ptr(),
|
||||
state.as_ptr(),
|
||||
value.as_ptr(),
|
||||
false, // don't copy more
|
||||
)
|
||||
})?;
|
||||
|
||||
fn delegate(
|
||||
inner: &LazyArray<StorePath, Box<dyn Fn(usize) -> StorePath>>,
|
||||
index: usize,
|
||||
) -> StorePath {
|
||||
// XXX: TODO
|
||||
// inner[index]
|
||||
StorePath::fake_path(unsafe { state.store_ref() }).unwrap()
|
||||
}
|
||||
|
||||
let size = unsafe { sys::nix_realised_string_get_store_path_count(inner.as_ptr()) };
|
||||
|
||||
Ok(Self {
|
||||
inner,
|
||||
path: Self::parse_path(inner.as_ptr(), state),
|
||||
// children: LazyArray::new(size, delegate as fn(usize) -> StorePath),
|
||||
children: LazyArray::<StorePath, Box<dyn Fn(usize) -> StorePath>>::new(
|
||||
size,
|
||||
Box::new(delegate),
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_path(
|
||||
realised_string: *mut sys::nix_realised_string,
|
||||
state: &Arc<EvalState>,
|
||||
) -> StorePath {
|
||||
let buffer_ptr = unsafe { sys::nix_realised_string_get_buffer_start(realised_string) };
|
||||
let buffer_size = unsafe { sys::nix_realised_string_get_buffer_size(realised_string) };
|
||||
|
||||
let path_str = (buffer_ptr as *const c_char)
|
||||
.to_utf8_string_n(buffer_size)
|
||||
.unwrap_or_else(|err| {
|
||||
panic_issue_call_failed!(
|
||||
"`sys::nix_realised_string_get_buffer_(start|size)` invalid UTF-8 ({})",
|
||||
err
|
||||
)
|
||||
});
|
||||
StorePath::parse(unsafe { state.store_ref() }, &path_str).unwrap_or_else(|err| {
|
||||
panic_issue_call_failed!(
|
||||
"`sys::nix_realised_string_get_buffer_(start|size)` invalid store path ({})",
|
||||
err
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -3,14 +3,12 @@ use std::sync::Arc;
|
|||
use serial_test::serial;
|
||||
|
||||
use super::{EvalStateBuilder, ValueType};
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::Store;
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn test_eval_state_builder() {
|
||||
let ctx = Arc::new(ErrorContext::new());
|
||||
let store = Arc::new(Store::open(&ctx, None).expect("Failed to open store"));
|
||||
let store = Arc::new(Store::open(None).expect("Failed to open store"));
|
||||
let _state = EvalStateBuilder::new(&store)
|
||||
.expect("Failed to create builder")
|
||||
.build()
|
||||
|
|
@ -21,8 +19,7 @@ fn test_eval_state_builder() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_simple_evaluation() {
|
||||
let ctx = Arc::new(ErrorContext::new());
|
||||
let store = Arc::new(Store::open(&ctx, None).expect("Failed to open store"));
|
||||
let store = Arc::new(Store::open(None).expect("Failed to open store"));
|
||||
let state = EvalStateBuilder::new(&store)
|
||||
.expect("Failed to create builder")
|
||||
.build()
|
||||
|
|
@ -39,8 +36,7 @@ fn test_simple_evaluation() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_value_types() {
|
||||
let ctx = Arc::new(ErrorContext::new());
|
||||
let store = Arc::new(Store::open(&ctx, None).expect("Failed to open store"));
|
||||
let store = Arc::new(Store::open(None).expect("Failed to open store"));
|
||||
let state = EvalStateBuilder::new(&store)
|
||||
.expect("Failed to create builder")
|
||||
.build()
|
||||
|
|
@ -71,8 +67,7 @@ fn test_value_types() {
|
|||
#[test]
|
||||
#[serial]
|
||||
fn test_value_formatting() {
|
||||
let ctx = Arc::new(ErrorContext::new());
|
||||
let store = Arc::new(Store::open(&ctx, None).expect("Failed to open store"));
|
||||
let store = Arc::new(Store::open(None).expect("Failed to open store"));
|
||||
let state = EvalStateBuilder::new(&store)
|
||||
.expect("Failed to create builder")
|
||||
.build()
|
||||
|
|
|
|||
|
|
@ -2,30 +2,40 @@ use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
|
|||
use std::ptr::NonNull;
|
||||
|
||||
use super::{EvalState, ValueType};
|
||||
use crate::errors::{new_nixide_error, ErrorContext, NixideError};
|
||||
use crate::errors::{ErrorContext, NixideResult};
|
||||
use crate::sys;
|
||||
use crate::util::wrappers::{AsInnerPtr, FromC as _};
|
||||
use crate::util::AsErr;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
use crate::util::{panic_issue_call_failed, wrap};
|
||||
|
||||
/// A Nix value
|
||||
///
|
||||
/// This represents any value in the Nix language, including primitives,
|
||||
/// collections, and functions.
|
||||
pub struct Value {
|
||||
pub struct Value<'a> {
|
||||
pub(crate) inner: NonNull<sys::nix_value>,
|
||||
state: &'a EvalState,
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::nix_value> for Value {
|
||||
impl<'a> AsInnerPtr<sys::nix_value> for Value<'a> {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::nix_value {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::nix_value {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::nix_value {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Value {
|
||||
pub(crate) unsafe fn new(inner: *mut sys::Value) -> Self {
|
||||
Value {
|
||||
inner: NonNull::new(inner).unwrap(),
|
||||
}
|
||||
impl<'a> Value<'a> {
|
||||
pub(crate) fn new(inner: NonNull<sys::nix_value>, state: &'a EvalState) -> Self {
|
||||
Value { inner, state }
|
||||
}
|
||||
|
||||
/// Force evaluation of this value.
|
||||
|
|
@ -35,12 +45,11 @@ impl Value {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if evaluation fails.
|
||||
pub fn force(&mut self, state: &EvalState) -> Result<(), NixideError> {
|
||||
pub fn force(&mut self) -> NixideResult<()> {
|
||||
// XXX: TODO: move force and force_deep to the EvalState
|
||||
let ctx = ErrorContext::new();
|
||||
|
||||
unsafe { sys::nix_value_force(ctx.as_ptr(), state.as_ptr(), self.as_ptr()) };
|
||||
ctx.peak()
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_value_force(ctx.as_ptr(), self.state.as_ptr(), self.as_ptr());
|
||||
})
|
||||
}
|
||||
|
||||
/// Force deep evaluation of this value.
|
||||
|
|
@ -50,132 +59,39 @@ impl Value {
|
|||
/// # Errors
|
||||
///
|
||||
/// Returns an error if evaluation fails.
|
||||
pub fn force_deep(&mut self, state: &EvalState) -> Result<(), NixideError> {
|
||||
let ctx = ErrorContext::new();
|
||||
|
||||
unsafe { sys::nix_value_force_deep(ctx.as_ptr(), state.as_ptr(), self.as_ptr()) };
|
||||
ctx.peak()
|
||||
pub fn force_deep(&mut self) -> NixideResult<()> {
|
||||
// XXX: TODO: move force and force_deep to the EvalState
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_value_force_deep(ctx.as_ptr(), self.state.as_ptr(), self.as_ptr());
|
||||
})
|
||||
}
|
||||
|
||||
/// Get the type of this value.
|
||||
#[must_use]
|
||||
pub fn value_type(&self) -> ValueType {
|
||||
let ctx = ErrorContext::new();
|
||||
let value_type =
|
||||
unsafe { ValueType::from_c(sys::nix_get_type(ctx.as_ptr(), self.as_ptr())) };
|
||||
// NOTE: an error here only occurs if `nix_get_type` catches an error,
|
||||
// NOTE: which in turn only happens if the `sys::nix_value*` is a null pointer
|
||||
// NOTE: or points to an uninitialised `nix_value` struct.
|
||||
ctx.peak().unwrap_or_else(|_| panic!("TODO im sleepy rn"));
|
||||
value_type
|
||||
ValueType::from({
|
||||
wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_get_type(ctx.as_ptr(), self.as_ptr())
|
||||
})
|
||||
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err))
|
||||
})
|
||||
}
|
||||
|
||||
fn expect_type(&self, expected: ValueType) -> Result<(), NixideError> {
|
||||
let got = self.value_type();
|
||||
if got != expected {
|
||||
return Err(new_nixide_error!(
|
||||
InvalidType,
|
||||
expected.to_string(),
|
||||
got.to_string()
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Convert this value to an integer.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value is not an integer.
|
||||
pub fn as_int(&self) -> Result<i64, NixideError> {
|
||||
self.expect_type(ValueType::Int)?;
|
||||
|
||||
let ctx = ErrorContext::new();
|
||||
let result = unsafe { sys::nix_get_int(ctx.as_ptr(), self.as_ptr()) };
|
||||
match ctx.peak() {
|
||||
Some(err) => Err(err),
|
||||
None => Ok(result),
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this value to a float.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value is not a float.
|
||||
pub fn as_float(&self) -> Result<f64, NixideError> {
|
||||
self.expect_type(ValueType::Float)?;
|
||||
|
||||
let ctx = ErrorContext::new();
|
||||
let result = unsafe { sys::nix_get_float(ctx.as_ptr(), self.as_ptr()) };
|
||||
match ctx.peak() {
|
||||
Some(err) => Err(err),
|
||||
None => Ok(result),
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this value to a boolean.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value is not a boolean.
|
||||
pub fn as_bool(&self) -> Result<bool, NixideError> {
|
||||
self.expect_type(ValueType::Bool)?;
|
||||
|
||||
let ctx = ErrorContext::new();
|
||||
let result = unsafe { sys::nix_get_bool(ctx.as_ptr(), self.as_ptr()) };
|
||||
match ctx.peak() {
|
||||
Some(err) => Err(err),
|
||||
None => Ok(result),
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this value to a string.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value is not a string.
|
||||
pub fn as_string(&self) -> Result<String, NixideError> {
|
||||
self.expect_type(ValueType::String)?;
|
||||
|
||||
let ctx = ErrorContext::new();
|
||||
|
||||
// For string values, we need to use realised string API
|
||||
let realised_str = unsafe {
|
||||
sys::nix_string_realise(
|
||||
ctx.as_ptr(),
|
||||
self.state.as_ptr(),
|
||||
self.as_ptr(),
|
||||
false, // don't copy more
|
||||
)
|
||||
};
|
||||
|
||||
if realised_str.is_null() {
|
||||
return Err(new_nixide_error!(NullPtr));
|
||||
}
|
||||
|
||||
let buffer_start = unsafe { sys::nix_realised_string_get_buffer_start(realised_str) };
|
||||
let buffer_size = unsafe { sys::nix_realised_string_get_buffer_size(realised_str) };
|
||||
if buffer_start.is_null() {
|
||||
// Clean up realised string
|
||||
unsafe {
|
||||
sys::nix_realised_string_free(realised_str);
|
||||
}
|
||||
return Err(new_nixide_error!(NullPtr));
|
||||
}
|
||||
|
||||
let bytes = unsafe { std::slice::from_raw_parts(buffer_start.cast::<u8>(), buffer_size) };
|
||||
let string = std::str::from_utf8(bytes)
|
||||
.map_err(|_| new_nixide_error!(StringNotUtf8))?
|
||||
.to_owned();
|
||||
|
||||
// Clean up realised string
|
||||
unsafe {
|
||||
sys::nix_realised_string_free(realised_str);
|
||||
}
|
||||
|
||||
Ok(string)
|
||||
}
|
||||
// XXX: TODO: rewrite `expr/value.rs` to make this redundant
|
||||
// fn expect_type(&self, expected: ValueType) -> NixideResult<()> {
|
||||
// let got = self.value_type();
|
||||
// if got != expected {
|
||||
// return Err(new_nixide_error!(
|
||||
// InvalidType,
|
||||
// expected.to_string(),
|
||||
// got.to_string()
|
||||
// ));
|
||||
// }
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
/// Format this value as Nix syntax.
|
||||
///
|
||||
|
|
@ -186,7 +102,7 @@ impl Value {
|
|||
///
|
||||
/// Returns an error if the value cannot be converted to a string
|
||||
/// representation.
|
||||
pub fn to_nix_string(&self) -> Result<String, NixideError> {
|
||||
pub fn to_nix_string(&self) -> NixideResult<String> {
|
||||
match self.value_type() {
|
||||
ValueType::Int => Ok(self.as_int()?.to_string()),
|
||||
ValueType::Float => Ok(self.as_float()?.to_string()),
|
||||
|
|
|
|||
0
nixide/src/expr/values/attrs.rs
Normal file
0
nixide/src/expr/values/attrs.rs
Normal file
70
nixide/src/expr/values/bool.rs
Normal file
70
nixide/src/expr/values/bool.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use super::NixValue;
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::sys;
|
||||
use crate::util::panic_issue_call_failed;
|
||||
use crate::util::wrap;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
|
||||
pub struct NixBool {
|
||||
inner: NonNull<sys::nix_value>,
|
||||
value: bool,
|
||||
}
|
||||
|
||||
impl Display for NixBool {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "<bool>")
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for NixBool {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "NixBool(${})", self.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::nix_value> for NixBool {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::nix_value {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::nix_value {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::nix_value {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl NixValue for NixBool {
|
||||
#[inline]
|
||||
fn get_enum_id(&self) -> sys::ValueType {
|
||||
sys::ValueType_NIX_TYPE_BOOL
|
||||
}
|
||||
|
||||
fn new(inner: NonNull<sys::nix_value>) -> Self {
|
||||
let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_get_bool(ctx.as_ptr(), inner.as_ptr())
|
||||
})
|
||||
.unwrap_or_else(|err| {
|
||||
panic_issue_call_failed!("`sys::nix_get_bool` failed for valid `NixBool` ({})", err)
|
||||
});
|
||||
|
||||
Self { inner, value }
|
||||
}
|
||||
}
|
||||
|
||||
impl NixBool {
|
||||
/// Returns a shared reference to the underlying value.
|
||||
///
|
||||
#[inline]
|
||||
fn value(&self) -> &bool {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
0
nixide/src/expr/values/external.rs
Normal file
0
nixide/src/expr/values/external.rs
Normal file
69
nixide/src/expr/values/float.rs
Normal file
69
nixide/src/expr/values/float.rs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use super::NixValue;
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::sys;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
use crate::util::{panic_issue_call_failed, wrap};
|
||||
|
||||
pub struct NixFloat {
|
||||
inner: NonNull<sys::nix_value>,
|
||||
value: f64,
|
||||
}
|
||||
|
||||
impl Display for NixFloat {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "<float>")
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for NixFloat {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "NixFloat(${})", self.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::nix_value> for NixFloat {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::nix_value {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::nix_value {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::nix_value {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl NixValue for NixFloat {
|
||||
#[inline]
|
||||
fn get_enum_id(&self) -> sys::ValueType {
|
||||
sys::ValueType_NIX_TYPE_FLOAT
|
||||
}
|
||||
|
||||
fn new(inner: NonNull<sys::nix_value>) -> Self {
|
||||
let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_get_float(ctx.as_ptr(), inner.as_ptr())
|
||||
})
|
||||
.unwrap_or_else(|err| {
|
||||
panic_issue_call_failed!("`sys::nix_get_float` failed for valid `NixFloat` ({})", err)
|
||||
});
|
||||
|
||||
Self { inner, value }
|
||||
}
|
||||
}
|
||||
|
||||
impl NixFloat {
|
||||
/// Returns a shared reference to the underlying value.
|
||||
///
|
||||
#[inline]
|
||||
fn value(&self) -> &f64 {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
0
nixide/src/expr/values/function.rs
Normal file
0
nixide/src/expr/values/function.rs
Normal file
69
nixide/src/expr/values/int.rs
Normal file
69
nixide/src/expr/values/int.rs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use super::NixValue;
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::sys;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
use crate::util::{panic_issue_call_failed, wrap};
|
||||
|
||||
pub struct NixInt {
|
||||
inner: NonNull<sys::nix_value>,
|
||||
value: i64,
|
||||
}
|
||||
|
||||
impl Display for NixInt {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "<int>")
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for NixInt {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "NixInt(${})", self.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::nix_value> for NixInt {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::nix_value {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::nix_value {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::nix_value {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl NixValue for NixInt {
|
||||
#[inline]
|
||||
fn get_enum_id(&self) -> sys::ValueType {
|
||||
sys::ValueType_NIX_TYPE_INT
|
||||
}
|
||||
|
||||
fn new(inner: NonNull<sys::nix_value>) -> Self {
|
||||
let value = wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
sys::nix_get_int(ctx.as_ptr(), inner.as_ptr())
|
||||
})
|
||||
.unwrap_or_else(|err| {
|
||||
panic_issue_call_failed!("`sys::nix_get_int` failed for valid `NixInt` ({})", err)
|
||||
});
|
||||
|
||||
Self { inner, value }
|
||||
}
|
||||
}
|
||||
|
||||
impl NixInt {
|
||||
/// Returns a shared reference to the underlying value.
|
||||
///
|
||||
#[inline]
|
||||
fn value(&self) -> &i64 {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
0
nixide/src/expr/values/list.rs
Normal file
0
nixide/src/expr/values/list.rs
Normal file
29
nixide/src/expr/values/mod.rs
Normal file
29
nixide/src/expr/values/mod.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
mod attrs;
|
||||
mod bool;
|
||||
mod external;
|
||||
mod float;
|
||||
mod function;
|
||||
mod int;
|
||||
mod list;
|
||||
mod null;
|
||||
mod path;
|
||||
mod string;
|
||||
mod thunk;
|
||||
|
||||
pub use bool::NixBool;
|
||||
pub use float::NixFloat;
|
||||
pub use int::NixInt;
|
||||
pub use string::NixString;
|
||||
|
||||
use std::fmt::{Debug, Display};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use crate::sys;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
|
||||
pub trait NixValue: Display + Debug + AsInnerPtr<sys::nix_value> {
|
||||
/// TODO
|
||||
fn get_enum_id(&self) -> sys::ValueType;
|
||||
|
||||
fn new(inner: NonNull<sys::nix_value>) -> Self;
|
||||
}
|
||||
0
nixide/src/expr/values/null.rs
Normal file
0
nixide/src/expr/values/null.rs
Normal file
0
nixide/src/expr/values/path.rs
Normal file
0
nixide/src/expr/values/path.rs
Normal file
75
nixide/src/expr/values/string.rs
Normal file
75
nixide/src/expr/values/string.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
use std::cell::LazyCell;
|
||||
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use super::NixValue;
|
||||
use crate::expr::RealisedString;
|
||||
use crate::util::panic_issue_call_failed;
|
||||
use crate::util::wrap;
|
||||
use crate::util::wrappers::AsInnerPtr;
|
||||
use crate::{sys, NixideResult};
|
||||
|
||||
pub struct NixString {
|
||||
inner: NonNull<sys::nix_value>,
|
||||
value: String,
|
||||
}
|
||||
|
||||
impl Display for NixString {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "<string>")
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for NixString {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "NixString(\"${}\")", self.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInnerPtr<sys::nix_value> for NixString {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::nix_value {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::nix_value {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::nix_value {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl NixValue for NixString {
|
||||
#[inline]
|
||||
fn get_enum_id(&self) -> sys::ValueType {
|
||||
sys::ValueType_NIX_TYPE_STRING
|
||||
}
|
||||
|
||||
fn new(inner: NonNull<sys::nix_value>) -> Self {
|
||||
// wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
|
||||
// sys::nix_get_int(ctx.as_ptr(), inner.as_ptr())
|
||||
// })
|
||||
// .unwrap_or_else(|err| {
|
||||
// panic_issue_call_failed!(
|
||||
// "`sys::nix_get_int` failed for valid `NixString` ({})",
|
||||
// err
|
||||
// )
|
||||
// })
|
||||
// };
|
||||
|
||||
Self { inner, value }
|
||||
}
|
||||
}
|
||||
|
||||
impl NixString {
|
||||
/// Returns a shared reference to the underlying value.
|
||||
///
|
||||
#[inline]
|
||||
fn value(&self) -> &String {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
0
nixide/src/expr/values/thunk.rs
Normal file
0
nixide/src/expr/values/thunk.rs
Normal file
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||
|
||||
use crate::{sys, util::wrappers::FromC};
|
||||
use crate::sys;
|
||||
|
||||
/// Nix value types.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
@ -29,8 +29,8 @@ pub enum ValueType {
|
|||
External,
|
||||
}
|
||||
|
||||
impl FromC<sys::ValueType> for ValueType {
|
||||
unsafe fn from_c(value_type: sys::ValueType) -> Self {
|
||||
impl From<sys::ValueType> for ValueType {
|
||||
fn from(value_type: sys::ValueType) -> Self {
|
||||
match value_type {
|
||||
sys::ValueType_NIX_TYPE_THUNK => ValueType::Thunk,
|
||||
sys::ValueType_NIX_TYPE_INT => ValueType::Int,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ pub extern crate libc;
|
|||
pub extern crate nixide_sys as sys;
|
||||
|
||||
pub(crate) mod errors;
|
||||
// mod expr;
|
||||
mod expr;
|
||||
// mod flake;
|
||||
mod stdext;
|
||||
mod store;
|
||||
|
|
@ -14,7 +14,7 @@ mod verbosity;
|
|||
mod version;
|
||||
|
||||
pub use errors::{NixError, NixideError, NixideResult};
|
||||
// pub use expr::{EvalState, EvalStateBuilder, Value, ValueType};
|
||||
pub use expr::{EvalState, EvalStateBuilder, Value, ValueType};
|
||||
pub use store::{Store, StorePath};
|
||||
pub use verbosity::NixVerbosity;
|
||||
pub use version::NixVersion;
|
||||
|
|
|
|||
|
|
@ -36,9 +36,20 @@ pub struct Store {
|
|||
}
|
||||
|
||||
impl AsInnerPtr<sys::Store> for Store {
|
||||
#[inline]
|
||||
unsafe fn as_ptr(&self) -> *mut sys::Store {
|
||||
self.inner.as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_ref(&self) -> &sys::Store {
|
||||
unsafe { self.inner.as_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn as_mut(&mut self) -> &mut sys::Store {
|
||||
unsafe { self.inner.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Store {
|
||||
|
|
|
|||
79
nixide/src/util/lazy_array.rs
Normal file
79
nixide/src/util/lazy_array.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LazyArray<T, F>
|
||||
where
|
||||
F: Fn(usize) -> T,
|
||||
{
|
||||
inner: Rc<RefCell<Vec<Option<T>>>>,
|
||||
size: usize,
|
||||
delegate: F,
|
||||
}
|
||||
|
||||
impl<T, F> LazyArray<T, F>
|
||||
where
|
||||
F: Fn(usize) -> T,
|
||||
{
|
||||
pub fn new(size: usize, delegate: F) -> LazyArray<T, F> {
|
||||
let mut vec = Vec::with_capacity(size);
|
||||
for _ in 0..size {
|
||||
vec.push(None);
|
||||
}
|
||||
|
||||
LazyArray {
|
||||
inner: Rc::new(RefCell::new(vec)),
|
||||
size,
|
||||
delegate,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `None` if `index < self.size` otherwise always succeeds
|
||||
/// (unless of course the callback you supply panics).
|
||||
///
|
||||
// pub fn get(&mut self, index: usize) -> Option<&T> {
|
||||
// // let x = self.inner.get(index).copied().and_then(|value| match value {
|
||||
// // Some(value) => Some(value),
|
||||
// // None => {
|
||||
// // // store the value first
|
||||
// // let value = (self.delegate)(index);
|
||||
// // self.inner[index] = Some(value);
|
||||
|
||||
// // // now get a reference to it
|
||||
// // if let Some(v) = &self.inner[index] {
|
||||
// // return Some(v);
|
||||
// // }
|
||||
// // None
|
||||
// // }
|
||||
// // })
|
||||
// match self.inner.clone().borrow().get(index) {
|
||||
// Some(Some(value)) => Some(value),
|
||||
// Some(None) => {
|
||||
// let mut inner = self.inner.clone().borrow_mut();
|
||||
// // store the value first
|
||||
// inner[index] = Some((self.delegate)(index));
|
||||
|
||||
// // now get a reference to it
|
||||
// inner[index].as_ref()
|
||||
// }
|
||||
// None => None,
|
||||
// }
|
||||
// }
|
||||
pub fn get(&mut self, index: usize) -> Option<Rc<T>> {
|
||||
if index >= self.size {
|
||||
return None;
|
||||
}
|
||||
|
||||
// let inner = self.inner.borrow();
|
||||
if let Some(value) = self.inner.borrow()[index].as_ref() {
|
||||
return Some(Rc::new(value));
|
||||
}
|
||||
|
||||
// drop(inner); // explicitly drop the borrow
|
||||
|
||||
let value = (self.delegate)(index);
|
||||
self.inner.borrow_mut()[index] = Some(value);
|
||||
|
||||
Some(Rc::new(self.inner.borrow()[index].unwrap()))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +1,8 @@
|
|||
#[macro_use]
|
||||
pub mod panic;
|
||||
mod lazy_array;
|
||||
pub(crate) mod wrap;
|
||||
pub mod wrappers;
|
||||
|
||||
pub(crate) use panic::*;
|
||||
|
||||
// use crate::NixideError;
|
||||
|
||||
// pub trait AsErr<T> {
|
||||
// fn as_err(self) -> Result<(), T>;
|
||||
// }
|
||||
|
||||
// impl AsErr<NixideError> for Option<NixideError> {
|
||||
// fn as_err(self) -> Result<(), NixideError> {
|
||||
// match self {
|
||||
// Some(err) => Err(err),
|
||||
// None => Ok(()),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub trait AsInnerPtr<T> {
|
||||
// /// Get a pointer to the underlying (`inner`) `libnix` C struct.
|
||||
// ///
|
||||
// /// # Safety
|
||||
// ///
|
||||
// /// Although this function isn't inherently `unsafe`, it is
|
||||
// /// marked as such intentionally to force calls to be wrapped
|
||||
// /// in `unsafe` blocks for clarity.
|
||||
// unsafe fn as_ptr(&self) -> *mut T;
|
||||
// }
|
||||
|
||||
// pub trait FromC<T> {
|
||||
// /// Creates a new instance of [Self] from the underlying
|
||||
// /// libnix C type [T].
|
||||
// unsafe fn from_c(value: T) -> Self;
|
||||
// }
|
||||
pub(crate) use lazy_array::LazyArray;
|
||||
pub(crate) use panic::{panic_issue, panic_issue_call_failed};
|
||||
|
|
|
|||
|
|
@ -1,26 +1,5 @@
|
|||
// use crate::NixideError;
|
||||
//
|
||||
// pub trait AsErr<T> {
|
||||
// fn as_err(self) -> Result<(), T>;
|
||||
// }
|
||||
//
|
||||
// impl AsErr<NixideError> for Option<NixideError> {
|
||||
// fn as_err(self) -> Result<(), NixideError> {
|
||||
// match self {
|
||||
// Some(err) => Err(err),
|
||||
// None => Ok(()),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// pub trait FromC<T> {
|
||||
// /// Creates a new instance of [Self] from the underlying
|
||||
// /// libnix C type [T].
|
||||
// unsafe fn from_c(value: T) -> Self;
|
||||
// }
|
||||
|
||||
pub trait AsInnerPtr<T> {
|
||||
/// Get a pointer to the underlying (`inner`) `libnix` C struct.
|
||||
/// Acquires the underlying pointer to the inner `libnix` C struct.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
|
|
@ -28,4 +7,26 @@ pub trait AsInnerPtr<T> {
|
|||
/// marked as such intentionally to force calls to be wrapped
|
||||
/// in `unsafe` blocks for clarity.
|
||||
unsafe fn as_ptr(&self) -> *mut T;
|
||||
|
||||
/// Returns a shared reference to the inner `libnix` C struct.
|
||||
///
|
||||
/// For the mutable counterpart see [AsInnerPtr<T>::as_mut].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Although this function isn't inherently `unsafe`, it is
|
||||
/// marked as such intentionally to force calls to be wrapped
|
||||
/// in `unsafe` blocks for clarity.
|
||||
unsafe fn as_ref(&self) -> &T;
|
||||
|
||||
/// Returns a unique reference to the inner `libnix` C struct.
|
||||
///
|
||||
/// For the shared counterpart see [AsInnerPtr<T>::as_ref].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Although this function isn't inherently `unsafe`, it is
|
||||
/// marked as such intentionally to force calls to be wrapped
|
||||
/// in `unsafe` blocks for clarity.
|
||||
unsafe fn as_mut(&mut self) -> &mut T;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue