175eb97505
This is required for constructing nested attribute sets at runtime. There'll be quite a lot of optimisation potential with this solution eventually, if it should turn out to be a bottleneck. This introduces a conceptual change, in that the `Value` enum is now an enum representing "all runtime values" instead of "all Nix language types". This makes sense in general, as this type will also contain Chunk representations etc. which are not exposed to users. Change-Id: Ic5f72b2a0965b146c6a451efad34c6a81ca1aad8 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6103 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
91 lines
2.4 KiB
Rust
91 lines
2.4 KiB
Rust
//! This module implements the backing representation of runtime
|
|
//! values in the Nix language.
|
|
use std::fmt::Display;
|
|
use std::rc::Rc;
|
|
|
|
mod attrs;
|
|
mod list;
|
|
mod string;
|
|
|
|
use crate::errors::{Error, EvalResult};
|
|
pub use attrs::NixAttrs;
|
|
pub use list::NixList;
|
|
pub use string::NixString;
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub enum Value {
|
|
Null,
|
|
Bool(bool),
|
|
Integer(i64),
|
|
Float(f64),
|
|
String(NixString),
|
|
Attrs(Rc<NixAttrs>),
|
|
List(NixList),
|
|
|
|
// Internal values that, while they technically exist at runtime,
|
|
// are never returned to or created directly by users.
|
|
AttrPath(Vec<NixString>),
|
|
}
|
|
|
|
impl Value {
|
|
pub fn is_number(&self) -> bool {
|
|
match self {
|
|
Value::Integer(_) => true,
|
|
Value::Float(_) => true,
|
|
_ => false,
|
|
}
|
|
}
|
|
|
|
pub fn type_of(&self) -> &'static str {
|
|
match self {
|
|
Value::Null => "null",
|
|
Value::Bool(_) => "bool",
|
|
Value::Integer(_) => "int",
|
|
Value::Float(_) => "float",
|
|
Value::String(_) => "string",
|
|
Value::Attrs(_) => "set",
|
|
Value::List(_) => "list",
|
|
|
|
// Internal types
|
|
Value::AttrPath(_) => "internal",
|
|
}
|
|
}
|
|
|
|
pub fn as_bool(self) -> EvalResult<bool> {
|
|
match self {
|
|
Value::Bool(b) => Ok(b),
|
|
other => Err(Error::TypeError {
|
|
expected: "bool",
|
|
actual: other.type_of(),
|
|
}),
|
|
}
|
|
}
|
|
|
|
pub fn as_string(self) -> EvalResult<NixString> {
|
|
match self {
|
|
Value::String(s) => Ok(s),
|
|
other => Err(Error::TypeError {
|
|
expected: "string",
|
|
actual: other.type_of(),
|
|
}),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for Value {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Value::Null => f.write_str("null"),
|
|
Value::Bool(true) => f.write_str("true"),
|
|
Value::Bool(false) => f.write_str("false"),
|
|
Value::Integer(num) => f.write_fmt(format_args!("{}", num)),
|
|
Value::Float(num) => f.write_fmt(format_args!("{}", num)),
|
|
Value::String(s) => s.fmt(f),
|
|
Value::Attrs(attrs) => attrs.fmt(f),
|
|
Value::List(list) => list.fmt(f),
|
|
|
|
// internal types
|
|
Value::AttrPath(_) => f.write_str("internal"),
|
|
}
|
|
}
|
|
}
|