forked from extern/nushell
Create Record
type (#10103)
# Description This PR creates a new `Record` type to reduce duplicate code and possibly bugs as well. (This is an edited version of #9648.) - `Record` implements `FromIterator` and `IntoIterator` and so can be iterated over or collected into. For example, this helps with conversions to and from (hash)maps. (Also, no more `cols.iter().zip(vals)`!) - `Record` has a `push(col, val)` function to help insure that the number of columns is equal to the number of values. I caught a few potential bugs thanks to this (e.g. in the `ls` command). - Finally, this PR also adds a `record!` macro that helps simplify record creation. It is used like so: ```rust record! { "key1" => some_value, "key2" => Value::string("text", span), "key3" => Value::int(optional_int.unwrap_or(0), span), "key4" => Value::bool(config.setting, span), } ``` Since macros hinder formatting, etc., the right hand side values should be relatively short and sweet like the examples above. Where possible, prefer `record!` or `.collect()` on an iterator instead of multiple `Record::push`s, since the first two automatically set the record capacity and do less work overall. # User-Facing Changes Besides the changes in `nu-protocol` the only other breaking changes are to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value,
|
||||
Category, Example, IntoPipelineData, PipelineData, Record, ShellError, Signature, Type, Value,
|
||||
};
|
||||
|
||||
use std::thread;
|
||||
@ -42,8 +42,7 @@ impl Command for Complete {
|
||||
exit_code,
|
||||
..
|
||||
} => {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
let mut record = Record::new();
|
||||
|
||||
// use a thread to receive stderr message.
|
||||
// Or we may get a deadlock if child process sends out too much bytes to stdout.
|
||||
@ -78,46 +77,35 @@ impl Command for Complete {
|
||||
});
|
||||
|
||||
if let Some(stdout) = stdout {
|
||||
cols.push("stdout".to_string());
|
||||
let stdout = stdout.into_bytes()?;
|
||||
if let Ok(st) = String::from_utf8(stdout.item.clone()) {
|
||||
vals.push(Value::String {
|
||||
val: st,
|
||||
span: stdout.span,
|
||||
})
|
||||
} else {
|
||||
vals.push(Value::Binary {
|
||||
val: stdout.item,
|
||||
span: stdout.span,
|
||||
})
|
||||
}
|
||||
record.push(
|
||||
"stdout",
|
||||
if let Ok(st) = String::from_utf8(stdout.item.clone()) {
|
||||
Value::string(st, stdout.span)
|
||||
} else {
|
||||
Value::binary(stdout.item, stdout.span)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if let Some((handler, stderr_span)) = stderr_handler {
|
||||
cols.push("stderr".to_string());
|
||||
let res = handler.join().map_err(|err| ShellError::ExternalCommand {
|
||||
label: "Fail to receive external commands stderr message".to_string(),
|
||||
help: format!("{err:?}"),
|
||||
span: stderr_span,
|
||||
})??;
|
||||
vals.push(res)
|
||||
record.push("stderr", res)
|
||||
};
|
||||
|
||||
if let Some(exit_code) = exit_code {
|
||||
let mut v: Vec<_> = exit_code.collect();
|
||||
|
||||
if let Some(v) = v.pop() {
|
||||
cols.push("exit_code".to_string());
|
||||
vals.push(v);
|
||||
record.push("exit_code", v);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::Record {
|
||||
cols,
|
||||
vals,
|
||||
span: call.head,
|
||||
}
|
||||
.into_pipeline_data())
|
||||
Ok(Value::record(record, call.head).into_pipeline_data())
|
||||
}
|
||||
_ => Err(ShellError::GenericError(
|
||||
"Complete only works with external streams".to_string(),
|
||||
|
@ -3,8 +3,8 @@ use std::time::Duration;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Type,
|
||||
Value,
|
||||
Category, Example, IntoInterruptiblePipelineData, PipelineData, Record, ShellError, Signature,
|
||||
Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -82,81 +82,41 @@ fn run_ps(engine_state: &EngineState, call: &Call) -> Result<PipelineData, Shell
|
||||
let long = call.has_flag("long");
|
||||
|
||||
for proc in nu_system::collect_proc(Duration::from_millis(100), false) {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
let mut record = Record::new();
|
||||
|
||||
cols.push("pid".to_string());
|
||||
vals.push(Value::Int {
|
||||
val: proc.pid() as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("ppid".to_string());
|
||||
vals.push(Value::Int {
|
||||
val: proc.ppid() as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("name".to_string());
|
||||
vals.push(Value::String {
|
||||
val: proc.name(),
|
||||
span,
|
||||
});
|
||||
record.push("pid", Value::int(proc.pid() as i64, span));
|
||||
record.push("ppid", Value::int(proc.ppid() as i64, span));
|
||||
record.push("name", Value::string(proc.name(), span));
|
||||
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
// Hide status on Windows until we can find a good way to support it
|
||||
cols.push("status".to_string());
|
||||
vals.push(Value::String {
|
||||
val: proc.status(),
|
||||
span,
|
||||
});
|
||||
record.push("status", Value::string(proc.status(), span));
|
||||
}
|
||||
|
||||
cols.push("cpu".to_string());
|
||||
vals.push(Value::Float {
|
||||
val: proc.cpu_usage(),
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("mem".to_string());
|
||||
vals.push(Value::Filesize {
|
||||
val: proc.mem_size() as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("virtual".to_string());
|
||||
vals.push(Value::Filesize {
|
||||
val: proc.virtual_size() as i64,
|
||||
span,
|
||||
});
|
||||
record.push("cpu", Value::float(proc.cpu_usage(), span));
|
||||
record.push("mem", Value::filesize(proc.mem_size() as i64, span));
|
||||
record.push("virtual", Value::filesize(proc.virtual_size() as i64, span));
|
||||
|
||||
if long {
|
||||
cols.push("command".to_string());
|
||||
vals.push(Value::String {
|
||||
val: proc.command(),
|
||||
span,
|
||||
});
|
||||
record.push("command", Value::string(proc.command(), span));
|
||||
#[cfg(windows)]
|
||||
{
|
||||
cols.push("cwd".to_string());
|
||||
vals.push(Value::String {
|
||||
val: proc.cwd(),
|
||||
span,
|
||||
});
|
||||
cols.push("environment".to_string());
|
||||
vals.push(Value::List {
|
||||
vals: proc
|
||||
.environ()
|
||||
.iter()
|
||||
.map(|x| Value::string(x.to_string(), span))
|
||||
.collect(),
|
||||
span,
|
||||
});
|
||||
record.push("cwd", Value::string(proc.cwd(), span));
|
||||
record.push(
|
||||
"environment",
|
||||
Value::list(
|
||||
proc.environ()
|
||||
.iter()
|
||||
.map(|x| Value::string(x.to_string(), span))
|
||||
.collect(),
|
||||
span,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
output.push(Value::Record { cols, vals, span });
|
||||
output.push(Value::record(record, span));
|
||||
}
|
||||
|
||||
Ok(output
|
||||
|
@ -2,8 +2,8 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, ShellError,
|
||||
Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||
record, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData,
|
||||
ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||
};
|
||||
use winreg::{enums::*, RegKey};
|
||||
|
||||
@ -120,15 +120,14 @@ fn registry_query(
|
||||
let mut reg_values = vec![];
|
||||
for (name, val) in reg_key.enum_values().flatten() {
|
||||
let (nu_value, reg_type) = reg_value_to_nu_value(val, call_span);
|
||||
reg_values.push(Value::Record {
|
||||
cols: vec!["name".to_string(), "value".to_string(), "type".to_string()],
|
||||
vals: vec![
|
||||
Value::string(name, call_span),
|
||||
nu_value,
|
||||
Value::string(format!("{:?}", reg_type), call_span),
|
||||
],
|
||||
span: *registry_key_span,
|
||||
})
|
||||
reg_values.push(Value::record(
|
||||
record! {
|
||||
"name" => Value::string(name, call_span),
|
||||
"value" => nu_value,
|
||||
"type" => Value::string(format!("{:?}", reg_type), call_span),
|
||||
},
|
||||
*registry_key_span,
|
||||
))
|
||||
}
|
||||
Ok(reg_values.into_pipeline_data(engine_state.ctrlc.clone()))
|
||||
} else {
|
||||
@ -138,15 +137,14 @@ fn registry_query(
|
||||
match reg_value {
|
||||
Ok(val) => {
|
||||
let (nu_value, reg_type) = reg_value_to_nu_value(val, call_span);
|
||||
Ok(Value::Record {
|
||||
cols: vec!["name".to_string(), "value".to_string(), "type".to_string()],
|
||||
vals: vec![
|
||||
Value::string(value.item, call_span),
|
||||
nu_value,
|
||||
Value::string(format!("{:?}", reg_type), call_span),
|
||||
],
|
||||
span: value.span,
|
||||
}
|
||||
Ok(Value::record(
|
||||
record! {
|
||||
"name" => Value::string(value.item, call_span),
|
||||
"value" => nu_value,
|
||||
"type" => Value::string(format!("{:?}", reg_type), call_span),
|
||||
},
|
||||
value.span,
|
||||
)
|
||||
.into_pipeline_data())
|
||||
}
|
||||
Err(_) => Err(ShellError::GenericError(
|
||||
|
@ -3,8 +3,8 @@ use chrono::Local;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, IntoPipelineData, LazyRecord, PipelineData, ShellError, Signature, Span,
|
||||
Type, Value,
|
||||
record, Category, Example, IntoPipelineData, LazyRecord, PipelineData, Record, ShellError,
|
||||
Signature, Span, Type, Value,
|
||||
};
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
use sysinfo::{
|
||||
@ -118,52 +118,20 @@ pub fn disks(span: Span) -> Value {
|
||||
|
||||
let mut output = vec![];
|
||||
for disk in sys.disks() {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
let device = trim_cstyle_null(disk.name().to_string_lossy().to_string());
|
||||
let typ = trim_cstyle_null(String::from_utf8_lossy(disk.file_system()).to_string());
|
||||
|
||||
cols.push("device".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(disk.name().to_string_lossy().to_string()),
|
||||
span,
|
||||
});
|
||||
let record = record! {
|
||||
"device" => Value::string(device, span),
|
||||
"type" => Value::string(typ, span),
|
||||
"mount" => Value::string(disk.mount_point().to_string_lossy(), span),
|
||||
"total" => Value::filesize(disk.total_space() as i64, span),
|
||||
"free" => Value::filesize(disk.available_space() as i64, span),
|
||||
"removable" => Value::bool(disk.is_removable(), span),
|
||||
"kind" => Value::string(format!("{:?}", disk.kind()), span),
|
||||
};
|
||||
|
||||
cols.push("type".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(String::from_utf8_lossy(disk.file_system()).to_string()),
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("mount".into());
|
||||
vals.push(Value::String {
|
||||
val: disk.mount_point().to_string_lossy().to_string(),
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("total".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: disk.total_space() as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("free".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: disk.available_space() as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("removable".into());
|
||||
vals.push(Value::Bool {
|
||||
val: disk.is_removable(),
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("kind".into());
|
||||
vals.push(Value::String {
|
||||
val: format!("{:?}", disk.kind()),
|
||||
span,
|
||||
});
|
||||
|
||||
output.push(Value::Record { cols, vals, span });
|
||||
output.push(Value::record(record, span));
|
||||
}
|
||||
Value::List { vals: output, span }
|
||||
}
|
||||
@ -175,28 +143,13 @@ pub fn net(span: Span) -> Value {
|
||||
|
||||
let mut output = vec![];
|
||||
for (iface, data) in sys.networks() {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
let record = record! {
|
||||
"name" => Value::string(trim_cstyle_null(iface.to_string()), span),
|
||||
"sent" => Value::filesize(data.total_transmitted() as i64, span),
|
||||
"recv" => Value::filesize(data.total_received() as i64, span),
|
||||
};
|
||||
|
||||
cols.push("name".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(iface.to_string()),
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("sent".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: data.total_transmitted() as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("recv".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: data.total_received() as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
output.push(Value::Record { cols, vals, span });
|
||||
output.push(Value::record(record, span));
|
||||
}
|
||||
Value::List { vals: output, span }
|
||||
}
|
||||
@ -212,54 +165,26 @@ pub fn cpu(span: Span) -> Value {
|
||||
|
||||
let mut output = vec![];
|
||||
for cpu in sys.cpus() {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
|
||||
cols.push("name".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(cpu.name().to_string()),
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("brand".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(cpu.brand().to_string()),
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("freq".into());
|
||||
vals.push(Value::Int {
|
||||
val: cpu.frequency() as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("cpu_usage".into());
|
||||
|
||||
// sysinfo CPU usage numbers are not very precise unless you wait a long time between refreshes.
|
||||
// Round to 1DP (chosen somewhat arbitrarily) so people aren't misled by high-precision floats.
|
||||
let rounded_usage = (cpu.cpu_usage() * 10.0).round() / 10.0;
|
||||
vals.push(Value::Float {
|
||||
val: rounded_usage as f64,
|
||||
span,
|
||||
});
|
||||
|
||||
let load_avg = sys.load_average();
|
||||
cols.push("load_average".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(format!(
|
||||
"{:.2}, {:.2}, {:.2}",
|
||||
load_avg.one, load_avg.five, load_avg.fifteen
|
||||
)),
|
||||
span,
|
||||
});
|
||||
let load_avg = trim_cstyle_null(format!(
|
||||
"{:.2}, {:.2}, {:.2}",
|
||||
load_avg.one, load_avg.five, load_avg.fifteen
|
||||
));
|
||||
|
||||
cols.push("vendor_id".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(cpu.vendor_id().to_string()),
|
||||
span,
|
||||
});
|
||||
let record = record! {
|
||||
"name" => Value::string(trim_cstyle_null(cpu.name().to_string()), span),
|
||||
"brand" => Value::string(trim_cstyle_null(cpu.brand().to_string()), span),
|
||||
"freq" => Value::int(cpu.frequency() as i64, span),
|
||||
"cpu_usage" => Value::float(rounded_usage as f64, span),
|
||||
"load_average" => Value::string(load_avg, span),
|
||||
"vendor_id" => Value::string(trim_cstyle_null(cpu.vendor_id().to_string()), span),
|
||||
};
|
||||
|
||||
output.push(Value::Record { cols, vals, span });
|
||||
output.push(Value::record(record, span));
|
||||
}
|
||||
|
||||
Value::List { vals: output, span }
|
||||
@ -269,9 +194,6 @@ pub fn mem(span: Span) -> Value {
|
||||
let mut sys = System::new();
|
||||
sys.refresh_memory();
|
||||
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
|
||||
let total_mem = sys.total_memory();
|
||||
let free_mem = sys.free_memory();
|
||||
let used_mem = sys.used_memory();
|
||||
@ -281,101 +203,53 @@ pub fn mem(span: Span) -> Value {
|
||||
let free_swap = sys.free_swap();
|
||||
let used_swap = sys.used_swap();
|
||||
|
||||
cols.push("total".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: total_mem as i64,
|
||||
span,
|
||||
});
|
||||
let record = record! {
|
||||
"total" => Value::filesize(total_mem as i64, span),
|
||||
"free" => Value::filesize(free_mem as i64, span),
|
||||
"used" => Value::filesize(used_mem as i64, span),
|
||||
"available" => Value::filesize(avail_mem as i64, span),
|
||||
"swap total" => Value::filesize(total_swap as i64, span),
|
||||
"swap free" => Value::filesize(free_swap as i64, span),
|
||||
"swap used" => Value::filesize(used_swap as i64, span),
|
||||
};
|
||||
|
||||
cols.push("free".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: free_mem as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("used".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: used_mem as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("available".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: avail_mem as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("swap total".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: total_swap as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("swap free".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: free_swap as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("swap used".into());
|
||||
vals.push(Value::Filesize {
|
||||
val: used_swap as i64,
|
||||
span,
|
||||
});
|
||||
|
||||
Value::Record { cols, vals, span }
|
||||
Value::record(record, span)
|
||||
}
|
||||
|
||||
pub fn host(span: Span) -> Value {
|
||||
let mut sys = System::new();
|
||||
sys.refresh_users_list();
|
||||
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
let mut record = Record::new();
|
||||
|
||||
if let Some(name) = sys.name() {
|
||||
cols.push("name".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(name),
|
||||
span,
|
||||
});
|
||||
record.push("name", Value::string(trim_cstyle_null(name), span));
|
||||
}
|
||||
if let Some(version) = sys.os_version() {
|
||||
cols.push("os_version".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(version),
|
||||
span,
|
||||
});
|
||||
record.push("os_version", Value::string(trim_cstyle_null(version), span));
|
||||
}
|
||||
|
||||
if let Some(long_version) = sys.long_os_version() {
|
||||
cols.push("long_os_version".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(long_version),
|
||||
span,
|
||||
});
|
||||
record.push(
|
||||
"long_os_version",
|
||||
Value::string(trim_cstyle_null(long_version), span),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(version) = sys.kernel_version() {
|
||||
cols.push("kernel_version".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(version),
|
||||
span,
|
||||
});
|
||||
record.push(
|
||||
"kernel_version",
|
||||
Value::string(trim_cstyle_null(version), span),
|
||||
);
|
||||
}
|
||||
if let Some(hostname) = sys.host_name() {
|
||||
cols.push("hostname".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(hostname),
|
||||
span,
|
||||
});
|
||||
record.push("hostname", Value::string(trim_cstyle_null(hostname), span));
|
||||
}
|
||||
|
||||
cols.push("uptime".into());
|
||||
vals.push(Value::Duration {
|
||||
val: 1000000000 * sys.uptime() as i64,
|
||||
span,
|
||||
});
|
||||
record.push(
|
||||
"uptime",
|
||||
Value::duration(1000000000 * sys.uptime() as i64, span),
|
||||
);
|
||||
|
||||
// Creates a new SystemTime from the specified number of whole seconds
|
||||
let d = UNIX_EPOCH + Duration::from_secs(sys.boot_time());
|
||||
@ -384,23 +258,10 @@ pub fn host(span: Span) -> Value {
|
||||
// Convert to local time and then rfc3339
|
||||
let timestamp_str = datetime.with_timezone(datetime.offset()).to_rfc3339();
|
||||
|
||||
cols.push("boot_time".into());
|
||||
vals.push(Value::String {
|
||||
val: timestamp_str,
|
||||
span,
|
||||
});
|
||||
record.push("boot_time", Value::string(timestamp_str, span));
|
||||
|
||||
let mut users = vec![];
|
||||
for user in sys.users() {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
|
||||
cols.push("name".into());
|
||||
vals.push(Value::String {
|
||||
val: trim_cstyle_null(user.name().to_string()),
|
||||
span,
|
||||
});
|
||||
|
||||
let mut groups = vec![];
|
||||
for group in user.groups() {
|
||||
groups.push(Value::String {
|
||||
@ -409,18 +270,19 @@ pub fn host(span: Span) -> Value {
|
||||
});
|
||||
}
|
||||
|
||||
cols.push("groups".into());
|
||||
vals.push(Value::List { vals: groups, span });
|
||||
let record = record! {
|
||||
"name" => Value::string(trim_cstyle_null(user.name().to_string()), span),
|
||||
"groups" => Value::list(groups, span),
|
||||
};
|
||||
|
||||
users.push(Value::Record { cols, vals, span });
|
||||
users.push(Value::record(record, span));
|
||||
}
|
||||
|
||||
if !users.is_empty() {
|
||||
cols.push("sessions".into());
|
||||
vals.push(Value::List { vals: users, span });
|
||||
record.push("sessions", Value::list(users, span));
|
||||
}
|
||||
|
||||
Value::Record { cols, vals, span }
|
||||
Value::record(record, span)
|
||||
}
|
||||
|
||||
pub fn temp(span: Span) -> Value {
|
||||
@ -431,35 +293,16 @@ pub fn temp(span: Span) -> Value {
|
||||
let mut output = vec![];
|
||||
|
||||
for component in sys.components() {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
|
||||
cols.push("unit".into());
|
||||
vals.push(Value::String {
|
||||
val: component.label().to_string(),
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("temp".into());
|
||||
vals.push(Value::Float {
|
||||
val: component.temperature() as f64,
|
||||
span,
|
||||
});
|
||||
|
||||
cols.push("high".into());
|
||||
vals.push(Value::Float {
|
||||
val: component.max() as f64,
|
||||
span,
|
||||
});
|
||||
let mut record = record! {
|
||||
"unit" => Value::string(component.label(), span),
|
||||
"temp" => Value::float(component.temperature() as f64, span),
|
||||
"high" => Value::float(component.max() as f64, span),
|
||||
};
|
||||
|
||||
if let Some(critical) = component.critical() {
|
||||
cols.push("critical".into());
|
||||
vals.push(Value::Float {
|
||||
val: critical as f64,
|
||||
span,
|
||||
});
|
||||
record.push("critical", Value::float(critical as f64, span));
|
||||
}
|
||||
output.push(Value::Record { cols, vals, span });
|
||||
output.push(Value::record(record, span));
|
||||
}
|
||||
|
||||
Value::List { vals: output, span }
|
||||
|
@ -1,6 +1,7 @@
|
||||
use log::trace;
|
||||
use nu_engine::env;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::record;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
@ -63,19 +64,14 @@ fn entry(
|
||||
cmd_type: impl Into<String>,
|
||||
span: Span,
|
||||
) -> Value {
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
|
||||
cols.push("command".to_string());
|
||||
vals.push(Value::string(arg.into(), span));
|
||||
|
||||
cols.push("path".to_string());
|
||||
vals.push(Value::string(path.into(), span));
|
||||
|
||||
cols.push("type".to_string());
|
||||
vals.push(Value::string(cmd_type.into(), span));
|
||||
|
||||
Value::Record { cols, vals, span }
|
||||
Value::record(
|
||||
record! {
|
||||
"command" => Value::string(arg.into(), span),
|
||||
"path" => Value::string(path.into(), span),
|
||||
"type" => Value::string(cmd_type.into(), span),
|
||||
},
|
||||
span,
|
||||
)
|
||||
}
|
||||
|
||||
fn get_entry_in_commands(engine_state: &EngineState, name: &str, span: Span) -> Option<Value> {
|
||||
|
Reference in New Issue
Block a user