Compare commits

...

2 commits

Author SHA1 Message Date
2ac4bcfb9a
fix expr/tests.rs 2026-03-29 14:51:20 +10:00
e0c444a699
add .#nightly devshell 2026-03-29 14:50:56 +10:00
15 changed files with 295 additions and 79 deletions

39
flake.lock generated
View file

@ -1,5 +1,26 @@
{ {
"nodes": { "nodes": {
"fenix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1774682177,
"narHash": "sha256-OVbuJnJLlbHE28eRMudjtA6NXz/ifuXSho79gvh6GHY=",
"owner": "nix-community",
"repo": "fenix",
"rev": "e0f515387df77b9fdbaaf81e7f866f0365474c18",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1773222311, "lastModified": 1773222311,
@ -18,10 +39,28 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"fenix": "fenix",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"systems": "systems" "systems": "systems"
} }
}, },
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1774569884,
"narHash": "sha256-E8iWEPzg7OnE0XXXjo75CX7xFauqzJuGZ5wSO9KS8Ek=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "443ddcddd0c73b07b799d052f5ef3b448c2f3508",
"type": "github"
},
"original": {
"owner": "rust-lang",
"ref": "nightly",
"repo": "rust-analyzer",
"type": "github"
}
},
"systems": { "systems": {
"locked": { "locked": {
"lastModified": 1681028828, "lastModified": 1681028828,

View file

@ -4,6 +4,11 @@
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
systems.url = "github:nix-systems/default"; systems.url = "github:nix-systems/default";
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = { outputs = {
@ -29,8 +34,11 @@
pkgs = mkPkgs system nixpkgs; pkgs = mkPkgs system nixpkgs;
}); });
in { in {
overlays.default = self: super: { overlays = {
libclang = super.llvmPackages_21.libclang; default = self: super: {
libclang = super.llvmPackages_21.libclang;
};
fenix = inputs.fenix.overlays.default;
}; };
devShells = forAllSystems ( devShells = forAllSystems (
@ -107,6 +115,91 @@
shellHook = postConfigure; shellHook = postConfigure;
env = let
inherit (llvmPackages) llvm libclang;
in {
LD_LIBRARY_PATH = builtins.toString (lib.makeLibraryPath buildInputs);
LIBCLANG_PATH = "${libclang.lib}/lib";
RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}";
BINDGEN_EXTRA_CLANG_ARGS = "--sysroot=${pkgs.glibc.dev}";
# `cargo-llvm-cov` reads these environment variables to find these binaries,
# which are needed to run the tests
LLVM_COV = "${llvm}/bin/llvm-cov";
LLVM_PROFDATA = "${llvm}/bin/llvm-profdata";
};
};
nightly = let
nixForBindings = pkgs.nixVersions.nix_2_32;
inherit (pkgs.rustc) llvmPackages;
in
pkgs.mkShell rec {
name = "nixide";
shell = "${pkgs.bash}/bin/bash";
strictDeps = true;
# packages we need at runtime
packages = with pkgs; [
llvmPackages.lld
lldb
(pkgs.fenix.complete.withComponents [
"cargo"
"clippy"
"rust-src"
"rustc"
"rustfmt"
])
rust-analyzer-nightly
# cargo-c
# cargo-llvm-cov
# cargo-nextest
];
# packages we need at build time
nativeBuildInputs = with pkgs; [
pkg-config
glibc.dev
nixForBindings.dev
rustPlatform.bindgenHook
];
# packages we link against
buildInputs = with pkgs; [
stdenv.cc
nixForBindings
];
# bindgen uses clang to generate bindings, but it doesn't know where to
# find our stdenv cc's headers, so when it's gcc, we need to tell it.
postConfigure = lib.optionalString pkgs.stdenv.cc.isGNU ''
#!/usr/bin/env bash
# REF: https://github.com/nixops4/nix-bindings-rust/blob/main/bindgen-gcc.sh
# Rust bindgen uses Clang to generate bindings, but that means that it can't
# find the "system" or compiler headers when the stdenv compiler is GCC.
# This script tells it where to find them.
echo "Extending BINDGEN_EXTRA_CLANG_ARGS with system include paths..." 2>&1
BINDGEN_EXTRA_CLANG_ARGS="$${BINDGEN_EXTRA_CLANG_ARGS:-}"
export BINDGEN_EXTRA_CLANG_ARGS
include_paths=$(
echo | $NIX_CC_UNWRAPPED -v -E -x c - 2>&1 \
| awk '/#include <...> search starts here:/{flag=1;next} \
/End of search list./{flag=0} \
flag==1 {print $1}'
)
for path in $include_paths; do
echo " - $path" 2>&1
BINDGEN_EXTRA_CLANG_ARGS="$BINDGEN_EXTRA_CLANG_ARGS -I$path"
done
'';
shellHook = postConfigure;
env = let env = let
inherit (llvmPackages) llvm libclang; inherit (llvmPackages) llvm libclang;
in { in {

View file

@ -82,7 +82,7 @@ impl EvalState {
); );
value value
}) })
.map(|ptr| Value::from((ptr, self))) .map(|ptr| Value::from((ptr, std::rc::Rc::new(std::cell::RefCell::new(self)))))
} }
/// Allocate a new value. /// Allocate a new value.
@ -96,7 +96,8 @@ impl EvalState {
sys::nix_alloc_value(ctx.as_ptr(), self.as_ptr()) sys::nix_alloc_value(ctx.as_ptr(), self.as_ptr())
})?; })?;
Ok(Value::from((inner, self))) // Ok(Value::from((inner, self)))
todo!()
} }
} }

View file

@ -2,7 +2,7 @@ use std::sync::Arc;
use serial_test::serial; use serial_test::serial;
use super::{EvalStateBuilder, ValueType}; use super::{EvalStateBuilder, Value};
use crate::Store; use crate::Store;
#[test] #[test]
@ -29,8 +29,12 @@ fn test_simple_evaluation() {
.eval_from_string("1 + 2", "<eval>") .eval_from_string("1 + 2", "<eval>")
.expect("Failed to evaluate expression"); .expect("Failed to evaluate expression");
assert_eq!(result.value_type(), ValueType::Int); assert!(matches!(result, Value::Int(_)));
assert_eq!(result.as_int().expect("Failed to get int value"), 3); if let Value::Int(value) = result {
assert_eq!(value.as_int(), 3);
} else {
unreachable!();
}
} }
#[test] #[test]
@ -46,22 +50,34 @@ fn test_value_types() {
let int_val = state let int_val = state
.eval_from_string("42", "<eval>") .eval_from_string("42", "<eval>")
.expect("Failed to evaluate int"); .expect("Failed to evaluate int");
assert_eq!(int_val.value_type(), ValueType::Int); assert!(matches!(int_val, Value::Int(_)));
assert_eq!(int_val.as_int().expect("Failed to get int"), 42); if let Value::Int(value) = int_val {
assert_eq!(value.as_int(), 42);
} else {
unreachable!();
}
// Test boolean // Test boolean
let bool_val = state let bool_val = state
.eval_from_string("true", "<eval>") .eval_from_string("true", "<eval>")
.expect("Failed to evaluate bool"); .expect("Failed to evaluate bool");
assert_eq!(bool_val.value_type(), ValueType::Bool); assert!(matches!(bool_val, Value::Bool(_)));
assert!(bool_val.as_bool().expect("Failed to get bool")); if let Value::Bool(value) = bool_val {
assert_eq!(value.as_bool(), true);
} else {
unreachable!();
}
// Test string // Test string
let str_val = state let string_val = state
.eval_from_string("\"hello\"", "<eval>") .eval_from_string("\"hello\"", "<eval>")
.expect("Failed to evaluate string"); .expect("Failed to evaluate string");
assert_eq!(str_val.value_type(), ValueType::String); assert!(matches!(string_val, Value::String(_)));
assert_eq!(str_val.as_string().expect("Failed to get string"), "hello"); if let Value::String(value) = string_val {
assert_eq!(value.as_string(), "hello");
} else {
unreachable!();
}
} }
#[test] #[test]
@ -78,35 +94,29 @@ fn test_value_formatting() {
.eval_from_string("42", "<eval>") .eval_from_string("42", "<eval>")
.expect("Failed to evaluate int"); .expect("Failed to evaluate int");
assert_eq!(format!("{int_val}"), "42"); assert_eq!(format!("{int_val}"), "42");
assert_eq!(format!("{int_val:?}"), "Value::Int(42)"); assert_eq!(format!("{int_val:?}"), "Value::Int(NixInt(42))");
assert_eq!(int_val.to_nix_string().expect("Failed to format"), "42");
// Test boolean formatting // Test boolean formatting
let bool_val = state let true_val = state
.eval_from_string("true", "<eval>") .eval_from_string("true", "<eval>")
.expect("Failed to evaluate bool"); .expect("Failed to evaluate bool");
assert_eq!(format!("{bool_val}"), "true"); assert_eq!(format!("{true_val}"), "true");
assert_eq!(format!("{bool_val:?}"), "Value::Bool(true)"); assert_eq!(format!("{true_val:?}"), "Value::Bool(NixBool(true))");
assert_eq!(bool_val.to_nix_string().expect("Failed to format"), "true");
let false_val = state let false_val = state
.eval_from_string("false", "<eval>") .eval_from_string("false", "<eval>")
.expect("Failed to evaluate bool"); .expect("Failed to evaluate bool");
assert_eq!(format!("{false_val}"), "false"); assert_eq!(format!("{false_val}"), "false");
assert_eq!( assert_eq!(format!("{false_val:?}"), "Value::Bool(NixBool(false))");
false_val.to_nix_string().expect("Failed to format"),
"false"
);
// Test string formatting // Test string formatting
let str_val = state let str_val = state
.eval_from_string("\"hello world\"", "<eval>") .eval_from_string("\"hello world\"", "<eval>")
.expect("Failed to evaluate string"); .expect("Failed to evaluate string");
assert_eq!(format!("{str_val}"), "hello world"); assert_eq!(format!("{str_val}"), "hello world");
assert_eq!(format!("{str_val:?}"), "Value::String(\"hello world\")");
assert_eq!( assert_eq!(
str_val.to_nix_string().expect("Failed to format"), format!("{str_val:?}"),
"\"hello world\"" "Value::String(NixString(\"hello world\"))"
); );
// Test string with quotes // Test string with quotes
@ -115,8 +125,8 @@ fn test_value_formatting() {
.expect("Failed to evaluate quoted string"); .expect("Failed to evaluate quoted string");
assert_eq!(format!("{quoted_str}"), "say \"hello\""); assert_eq!(format!("{quoted_str}"), "say \"hello\"");
assert_eq!( assert_eq!(
quoted_str.to_nix_string().expect("Failed to format"), format!("{quoted_str:?}"),
"\"say \\\"hello\\\"\"" "Value::String(NixString(say \"hello\"))"
); );
// Test null formatting // Test null formatting
@ -124,8 +134,7 @@ fn test_value_formatting() {
.eval_from_string("null", "<eval>") .eval_from_string("null", "<eval>")
.expect("Failed to evaluate null"); .expect("Failed to evaluate null");
assert_eq!(format!("{null_val}"), "null"); assert_eq!(format!("{null_val}"), "null");
assert_eq!(format!("{null_val:?}"), "Value::Null"); assert_eq!(format!("{null_val:?}"), "Value::Null(NixNull)");
assert_eq!(null_val.to_nix_string().expect("Failed to format"), "null");
// Test collection formatting // Test collection formatting
let attrs_val = state let attrs_val = state

View file

@ -28,13 +28,13 @@ impl Drop for NixAttrs {
impl Display for NixAttrs { impl Display for NixAttrs {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "<attrs>") write!(f, "{{ <attrs> }}")
} }
} }
impl Debug for NixAttrs { impl Debug for NixAttrs {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "NixAttrs") write!(f, "NixAttrs({{ <attrs> }})") // XXX: TODO: format attrNames into here
} }
} }

View file

@ -27,13 +27,13 @@ impl Drop for NixBool {
impl Display for NixBool { impl Display for NixBool {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "<bool>") write!(f, "{}", self.value())
} }
} }
impl Debug for NixBool { impl Debug for NixBool {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "NixBool(${})", self.value) write!(f, "NixBool({})", self.value)
} }
} }
@ -80,7 +80,12 @@ impl NixBool {
/// Returns a shared reference to the underlying value. /// Returns a shared reference to the underlying value.
/// ///
#[inline] #[inline]
fn value(&self) -> &bool { pub fn value(&self) -> &bool {
&self.value &self.value
} }
#[inline]
pub fn as_bool(&self) -> bool {
self.value
}
} }

View file

@ -26,13 +26,13 @@ impl Drop for NixFloat {
impl Display for NixFloat { impl Display for NixFloat {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "<float>") write!(f, "{}", self.value())
} }
} }
impl Debug for NixFloat { impl Debug for NixFloat {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "NixFloat(${})", self.value()) write!(f, "NixFloat({})", self.value())
} }
} }
@ -79,7 +79,12 @@ impl NixFloat {
/// Returns a shared reference to the underlying value. /// Returns a shared reference to the underlying value.
/// ///
#[inline] #[inline]
fn value(&self) -> &f64 { pub fn value(&self) -> &f64 {
&self.value &self.value
} }
#[inline]
pub fn as_float(&self) -> f64 {
self.value
}
} }

View file

@ -74,14 +74,8 @@ impl NixValue for NixFunction {
} }
} }
// impl Fn<(Value,)> for NixFunction {
// extern "rust-call" fn call(&self, args: (Value,)) -> Value {
// args.0
// }
// }
impl NixFunction { impl NixFunction {
fn call<T>(&self, arg: &T) -> Value pub fn call<T>(&self, arg: &T) -> Value
where where
T: NixValue, T: NixValue,
{ {
@ -104,7 +98,7 @@ impl NixFunction {
Value::from((inner, self.state.clone())) Value::from((inner, self.state.clone()))
} }
fn call_many<T>(&self, args: &[&T]) -> Value pub fn call_many<T>(&self, args: &[&T]) -> Value
where where
T: NixValue, T: NixValue,
{ {
@ -128,3 +122,13 @@ impl NixFunction {
Value::from((inner, self.state.clone())) Value::from((inner, self.state.clone()))
} }
} }
// #[cfg(nightly)]
// impl<T> Fn<(&T,)> for NixFunction
// where
// T: NixValue,
// {
// extern "rust-call" fn call(&self, args: (&T,)) -> Value {
// self.call(args.0)
// }
// }

View file

@ -26,13 +26,13 @@ impl Drop for NixInt {
impl Display for NixInt { impl Display for NixInt {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "<int>") write!(f, "{}", self.value())
} }
} }
impl Debug for NixInt { impl Debug for NixInt {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "NixInt(${})", self.value()) write!(f, "NixInt({})", self.value())
} }
} }
@ -77,7 +77,12 @@ impl NixInt {
/// Returns a shared reference to the underlying value. /// Returns a shared reference to the underlying value.
/// ///
#[inline] #[inline]
fn value(&self) -> &i64 { pub fn value(&self) -> &i64 {
&self.value &self.value
} }
#[inline]
pub fn as_int(&self) -> i64 {
self.value
}
} }

View file

@ -26,13 +26,13 @@ impl Drop for NixList {
impl Display for NixList { impl Display for NixList {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "<list>") write!(f, "[ <list> ]")
} }
} }
impl Debug for NixList { impl Debug for NixList {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "NixList") write!(f, "NixList([ <list> ])")
} }
} }
@ -76,7 +76,7 @@ impl NixValue for NixList {
impl NixList { impl NixList {
/// Forces the evaluation on all elements of the list. /// Forces the evaluation on all elements of the list.
/// ///
fn as_vec(&self) -> Vec<Value> { pub fn as_vec(&self) -> Vec<Value> {
// XXX: TODO: should I just return a LazyArray instead? // XXX: TODO: should I just return a LazyArray instead?
let mut value = Vec::new(); let mut value = Vec::new();
for i in 0..self.len() { for i in 0..self.len() {
@ -86,7 +86,7 @@ impl NixList {
value value
} }
fn as_vec_lazy(&self) -> Vec<NixThunk> { pub fn as_vec_lazy(&self) -> Vec<NixThunk> {
// XXX: TODO: should I just return a LazyArray instead? // XXX: TODO: should I just return a LazyArray instead?
let mut value = Vec::new(); let mut value = Vec::new();
for i in 0..self.len() { for i in 0..self.len() {
@ -99,14 +99,14 @@ impl NixList {
/// Get the length of a list. This function preserves /// Get the length of a list. This function preserves
/// laziness and does not evaluate the internal fields. /// laziness and does not evaluate the internal fields.
/// ///
fn len(&self) -> u32 { pub fn len(&self) -> u32 {
wrap::nix_fn!(|ctx: &ErrorContext| unsafe { wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_list_size(ctx.as_ptr(), self.as_ptr()) sys::nix_get_list_size(ctx.as_ptr(), self.as_ptr())
}) })
.unwrap_or_else(|err| panic_issue_call_failed!("{}", err)) .unwrap_or_else(|err| panic_issue_call_failed!("{}", err))
} }
fn get(&self, index: u32) -> Value { pub fn get(&self, index: u32) -> Value {
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_list_byidx( sys::nix_get_list_byidx(
ctx.as_ptr(), ctx.as_ptr(),
@ -120,7 +120,7 @@ impl NixList {
Value::from((inner, self.state.clone())) Value::from((inner, self.state.clone()))
} }
fn get_lazy(&self, index: u32) -> NixThunk { pub fn get_lazy(&self, index: u32) -> NixThunk {
let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe { let inner = wrap::nix_ptr_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_get_list_byidx_lazy( sys::nix_get_list_byidx_lazy(
ctx.as_ptr(), ctx.as_ptr(),

View file

@ -12,7 +12,7 @@ mod thunk;
pub use attrs::NixAttrs; pub use attrs::NixAttrs;
pub use bool::NixBool; pub use bool::NixBool;
pub use external::NixExternal; // pub use external::NixExternal;
// pub use failed::NixFailed; // only in latest nix version // pub use failed::NixFailed; // only in latest nix version
pub use float::NixFloat; pub use float::NixFloat;
pub use function::NixFunction; pub use function::NixFunction;
@ -24,7 +24,7 @@ pub use string::NixString;
pub use thunk::NixThunk; pub use thunk::NixThunk;
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc; use std::rc::Rc;
@ -107,12 +107,8 @@ pub enum Value {
/// TODO /// TODO
Function(NixFunction), Function(NixFunction),
// External(NixExternal),
/// TODO // Failed(NixFailed),
External(NixExternal),
/// TODO
Failed(NixFailed),
} }
impl From<(NonNull<sys::nix_value>, Rc<RefCell<EvalState>>)> for Value { impl From<(NonNull<sys::nix_value>, Rc<RefCell<EvalState>>)> for Value {
@ -142,13 +138,61 @@ impl From<(NonNull<sys::nix_value>, Rc<RefCell<EvalState>>)> for Value {
ValueType_NIX_TYPE_FUNCTION => { ValueType_NIX_TYPE_FUNCTION => {
Value::Function(<NixFunction as NixValue>::from(inner, state)) Value::Function(<NixFunction as NixValue>::from(inner, state))
}, },
ValueType_NIX_TYPE_EXTERNAL => { // ValueType_NIX_TYPE_EXTERNAL => {
Value::External(<NixExternal as NixValue>::from(inner, state)) // Value::External(<NixExternal as NixValue>::from(inner, state))
}, // },
// | sys::ValueType_NIX_TYPE_FAILED => { // ValueType_NIX_TYPE_FAILED => {
// Value::Failed(<NixFailed as NixValue>::from(inner, state)) // Value::Failed(<NixFailed as NixValue>::from(inner, state))
// }, // },
_ => unreachable!(), _ => unreachable!(),
} }
} }
} }
impl Display for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Value::Thunk(value) => write!(f, "{value}"),
Value::Int(value) => write!(f, "{value}"),
Value::Float(value) => write!(f, "{value}"),
Value::Bool(value) => write!(f, "{value}"),
Value::String(value) => write!(f, "{value}"),
Value::Path(value) => write!(f, "{value}"),
Value::Null(value) => write!(f, "{value}"),
Value::Attrs(value) => write!(f, "{value}"),
Value::List(value) => write!(f, "{value}"),
Value::Function(value) => write!(f, "{value}"),
// Value::External(value) => write!(f, "{value}"),
// Value::Failed(value) => write!(f, "{value}"),
}
}
}
impl Debug for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Value::Thunk(value) => write!(f, "Value::Thunk({value:?})"),
Value::Int(value) => write!(f, "Value::Int({value:?})"),
Value::Float(value) => write!(f, "Value::Float({value:?})"),
Value::Bool(value) => write!(f, "Value::Bool({value:?})"),
Value::String(value) => write!(f, "Value::String({value:?})"),
Value::Path(value) => write!(f, "Value::Path({value:?})"),
Value::Null(value) => write!(f, "Value::Null({value:?})"),
Value::Attrs(value) => write!(f, "Value::Attrs({value:?})"),
Value::List(value) => write!(f, "Value::List({value:?})"),
Value::Function(value) => write!(f, "Value::Function({value:?})"),
// Value::External(value) => write!(f, "Value::External({value:?})"),
// Value::Failed(value) => write!(f, "Value::Failed({value:?})"),
}
}
}
// macro_rules! is_type {
// ($expr:expr, $tt:tt) => {{
// match $expr {
// $tt => true,
// _ => false,
// }
// }};
// }
// pub(self) use is_type;

View file

@ -29,13 +29,13 @@ impl Drop for NixPath {
impl Display for NixPath { impl Display for NixPath {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "<path>") write!(f, "{}", self.value.display())
} }
} }
impl Debug for NixPath { impl Debug for NixPath {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "NixPath(\"${}\")", self.value().display()) write!(f, "NixPath(\"{}\")", self.value().display())
} }
} }
@ -82,7 +82,12 @@ impl NixPath {
/// Returns a shared reference to the underlying value. /// Returns a shared reference to the underlying value.
/// ///
#[inline] #[inline]
fn value(&self) -> &PathBuf { pub fn value(&self) -> &PathBuf {
&self.value &self.value
} }
#[inline]
pub fn as_path(&self) -> PathBuf {
self.value.clone()
}
} }

View file

@ -28,13 +28,13 @@ impl Drop for NixString {
impl Display for NixString { impl Display for NixString {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "<string>") write!(f, "{}", self.value())
} }
} }
impl Debug for NixString { impl Debug for NixString {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "NixString(\"${}\")", self.value()) write!(f, "NixString(\"{}\")", self.value())
} }
} }
@ -86,7 +86,12 @@ impl NixString {
/// Returns a shared reference to the underlying value. /// Returns a shared reference to the underlying value.
/// ///
#[inline] #[inline]
fn value(&self) -> &String { pub fn value(&self) -> &String {
&self.value &self.value
} }
#[inline]
pub fn as_string(&self) -> String {
self.value.clone()
}
} }

View file

@ -65,11 +65,11 @@ impl NixValue for NixThunk {
} }
impl NixThunk { impl NixThunk {
fn to_inner(self) -> NonNull<sys::nix_value> { // fn to_inner(self) -> NonNull<sys::nix_value> {
self.inner // self.inner
} // }
fn eval(self) -> Value { pub fn eval(self) -> Value {
wrap::nix_fn!(|ctx: &ErrorContext| unsafe { wrap::nix_fn!(|ctx: &ErrorContext| unsafe {
sys::nix_value_force( sys::nix_value_force(
ctx.as_ptr(), ctx.as_ptr(),

View file

@ -1,6 +1,7 @@
// #![warn(missing_docs)] // #![warn(missing_docs)]
#![cfg_attr(nightly, feature(fn_traits))] #![cfg_attr(nightly, feature(fn_traits))]
#![cfg_attr(nightly, feature(unboxed_closures))]
pub extern crate libc; pub extern crate libc;
pub extern crate nixide_sys as sys; pub extern crate nixide_sys as sys;