mirror of
https://github.com/nushell/nushell
synced 2024-12-29 06:23:11 +00:00
Another batch of removing async_stream (#1970)
This commit is contained in:
parent
731aa6bbdd
commit
935a5f6b9e
5 changed files with 217 additions and 204 deletions
|
@ -45,8 +45,7 @@ impl WholeStreamCommand for Alias {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
// args.process(registry, alias)?.run()
|
alias(args, registry).await
|
||||||
alias(args, registry)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -65,63 +64,78 @@ impl WholeStreamCommand for Alias {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// <<<<<<< HEAD
|
pub async fn alias(
|
||||||
// pub fn alias(alias_args: AliasArgs, ctx: RunnableContext) -> Result<OutputStream, ShellError> {
|
args: CommandArgs,
|
||||||
// =======
|
registry: &CommandRegistry,
|
||||||
pub fn alias(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
let stream = async_stream! {
|
let mut raw_input = args.raw_input.clone();
|
||||||
let mut raw_input = args.raw_input.clone();
|
let (
|
||||||
let (AliasArgs { name, args: list, block, save}, ctx) = args.process(®istry).await?;
|
AliasArgs {
|
||||||
let mut processed_args: Vec<String> = vec![];
|
name,
|
||||||
|
args: list,
|
||||||
|
block,
|
||||||
|
save,
|
||||||
|
},
|
||||||
|
_ctx,
|
||||||
|
) = args.process(®istry).await?;
|
||||||
|
let mut processed_args: Vec<String> = vec![];
|
||||||
|
|
||||||
if let Some(true) = save {
|
if let Some(true) = save {
|
||||||
let mut result = crate::data::config::read(name.clone().tag, &None)?;
|
let mut result = crate::data::config::read(name.clone().tag, &None)?;
|
||||||
|
|
||||||
// process the alias to remove the --save flag
|
// process the alias to remove the --save flag
|
||||||
let left_brace = raw_input.find('{').unwrap_or(0);
|
let left_brace = raw_input.find('{').unwrap_or(0);
|
||||||
let right_brace = raw_input.rfind('}').unwrap_or(raw_input.len());
|
let right_brace = raw_input.rfind('}').unwrap_or_else(|| raw_input.len());
|
||||||
let mut left = raw_input[..left_brace].replace("--save", "").replace("-s", "");
|
let left = raw_input[..left_brace]
|
||||||
let mut right = raw_input[right_brace..].replace("--save", "").replace("-s", "");
|
.replace("--save", "")
|
||||||
raw_input = format!("{}{}{}", left, &raw_input[left_brace..right_brace], right);
|
.replace("-s", "");
|
||||||
|
let right = raw_input[right_brace..]
|
||||||
|
.replace("--save", "")
|
||||||
|
.replace("-s", "");
|
||||||
|
raw_input = format!("{}{}{}", left, &raw_input[left_brace..right_brace], right);
|
||||||
|
|
||||||
// create a value from raw_input alias
|
// create a value from raw_input alias
|
||||||
let alias: Value = raw_input.trim().to_string().into();
|
let alias: Value = raw_input.trim().to_string().into();
|
||||||
let alias_start = raw_input.find("[").unwrap_or(0); // used to check if the same alias already exists
|
let alias_start = raw_input.find('[').unwrap_or(0); // used to check if the same alias already exists
|
||||||
|
|
||||||
// add to startup if alias doesn't exist and replce if it does
|
// add to startup if alias doesn't exist and replce if it does
|
||||||
match result.get_mut("startup") {
|
match result.get_mut("startup") {
|
||||||
Some(startup) => {
|
Some(startup) => {
|
||||||
if let UntaggedValue::Table(ref mut commands) = startup.value {
|
if let UntaggedValue::Table(ref mut commands) = startup.value {
|
||||||
if let Some(command) = commands.iter_mut().find(|command| {
|
if let Some(command) = commands.iter_mut().find(|command| {
|
||||||
let cmd_str = command.as_string().unwrap_or_default();
|
let cmd_str = command.as_string().unwrap_or_default();
|
||||||
cmd_str.starts_with(&raw_input[..alias_start])
|
cmd_str.starts_with(&raw_input[..alias_start])
|
||||||
}) {
|
}) {
|
||||||
*command = alias;
|
*command = alias;
|
||||||
} else {
|
} else {
|
||||||
commands.push(alias);
|
commands.push(alias);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
|
||||||
let mut table = UntaggedValue::table(&[alias]);
|
|
||||||
result.insert("startup".to_string(), table.into_value(Tag::default()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
config::write(&result, &None)?;
|
None => {
|
||||||
}
|
let table = UntaggedValue::table(&[alias]);
|
||||||
|
result.insert("startup".to_string(), table.into_value(Tag::default()));
|
||||||
for item in list.iter() {
|
|
||||||
if let Ok(string) = item.as_string() {
|
|
||||||
processed_args.push(format!("${}", string));
|
|
||||||
} else {
|
|
||||||
yield Err(ShellError::labeled_error("Expected a string", "expected a string", item.tag()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield ReturnSuccess::action(CommandAction::AddAlias(name.to_string(), processed_args, block.clone()))
|
config::write(&result, &None)?;
|
||||||
};
|
}
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
for item in list.iter() {
|
||||||
|
if let Ok(string) = item.as_string() {
|
||||||
|
processed_args.push(format!("${}", string));
|
||||||
|
} else {
|
||||||
|
return Err(ShellError::labeled_error(
|
||||||
|
"Expected a string",
|
||||||
|
"expected a string",
|
||||||
|
item.tag(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(OutputStream::one(ReturnSuccess::action(
|
||||||
|
CommandAction::AddAlias(name.to_string(), processed_args, block),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -4,9 +4,7 @@ use crate::utils::data_processing::{reducer_for, Reduce};
|
||||||
use bigdecimal::FromPrimitive;
|
use bigdecimal::FromPrimitive;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::{convert_number_to_u64, Number, Operator};
|
use nu_protocol::hir::{convert_number_to_u64, Number, Operator};
|
||||||
use nu_protocol::{
|
use nu_protocol::{Dictionary, Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
|
||||||
Dictionary, Primitive, ReturnSuccess, ReturnValue, Signature, UntaggedValue, Value,
|
|
||||||
};
|
|
||||||
use num_traits::identities::Zero;
|
use num_traits::identities::Zero;
|
||||||
|
|
||||||
use indexmap::map::IndexMap;
|
use indexmap::map::IndexMap;
|
||||||
|
@ -42,6 +40,7 @@ impl WholeStreamCommand for Average {
|
||||||
name: args.call_info.name_tag,
|
name: args.call_info.name_tag,
|
||||||
raw_input: args.raw_input,
|
raw_input: args.raw_input,
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -53,53 +52,48 @@ impl WholeStreamCommand for Average {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn average(
|
async fn average(
|
||||||
RunnableContext {
|
RunnableContext {
|
||||||
mut input, name, ..
|
mut input, name, ..
|
||||||
}: RunnableContext,
|
}: RunnableContext,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
let stream = async_stream! {
|
let values: Vec<Value> = input.drain_vec().await;
|
||||||
let mut values: Vec<Value> = input.drain_vec().await;
|
|
||||||
let action = reducer_for(Reduce::Sum);
|
|
||||||
|
|
||||||
if values.iter().all(|v| if let UntaggedValue::Primitive(_) = v.value {true} else {false}) {
|
if values.iter().all(|v| v.is_primitive()) {
|
||||||
match avg(&values, name) {
|
match avg(&values, name) {
|
||||||
Ok(result) => yield ReturnSuccess::value(result),
|
Ok(result) => Ok(OutputStream::one(ReturnSuccess::value(result))),
|
||||||
Err(err) => yield Err(err),
|
Err(err) => Err(err),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut column_values = IndexMap::new();
|
let mut column_values = IndexMap::new();
|
||||||
for value in values {
|
for value in values {
|
||||||
match value.value {
|
if let UntaggedValue::Row(row_dict) = value.value {
|
||||||
UntaggedValue::Row(row_dict) => {
|
for (key, value) in row_dict.entries.iter() {
|
||||||
for (key, value) in row_dict.entries.iter() {
|
column_values
|
||||||
column_values
|
.entry(key.clone())
|
||||||
.entry(key.clone())
|
.and_modify(|v: &mut Vec<Value>| v.push(value.clone()))
|
||||||
.and_modify(|v: &mut Vec<Value>| v.push(value.clone()))
|
.or_insert(vec![value.clone()]);
|
||||||
.or_insert(vec![value.clone()]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
table => {},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut column_totals = IndexMap::new();
|
|
||||||
for (col_name, col_vals) in column_values {
|
|
||||||
match avg(&col_vals, &name) {
|
|
||||||
Ok(result) => {
|
|
||||||
column_totals.insert(col_name, result);
|
|
||||||
}
|
|
||||||
Err(err) => yield Err(err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield ReturnSuccess::value(
|
|
||||||
UntaggedValue::Row(Dictionary {entries: column_totals}).into_untagged_value())
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let stream: BoxStream<'static, ReturnValue> = stream.boxed();
|
let mut column_totals = IndexMap::new();
|
||||||
|
for (col_name, col_vals) in column_values {
|
||||||
|
match avg(&col_vals, &name) {
|
||||||
|
Ok(result) => {
|
||||||
|
column_totals.insert(col_name, result);
|
||||||
|
}
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
|
UntaggedValue::Row(Dictionary {
|
||||||
|
entries: column_totals,
|
||||||
|
})
|
||||||
|
.into_untagged_value(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn avg(values: &[Value], name: impl Into<Tag>) -> Result<Value, ShellError> {
|
fn avg(values: &[Value], name: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||||
|
|
|
@ -54,7 +54,7 @@ documentation link at https://docs.rs/encoding_rs/0.8.23/encoding_rs/#statics"#
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
enter(args, registry)
|
enter(args, registry).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -78,121 +78,122 @@ documentation link at https://docs.rs/encoding_rs/0.8.23/encoding_rs/#statics"#
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter(raw_args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn enter(
|
||||||
|
raw_args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
let stream = async_stream! {
|
let scope = raw_args.call_info.scope.clone();
|
||||||
let scope = raw_args.call_info.scope.clone();
|
let shell_manager = raw_args.shell_manager.clone();
|
||||||
let shell_manager = raw_args.shell_manager.clone();
|
let head = raw_args.call_info.args.head.clone();
|
||||||
let head = raw_args.call_info.args.head.clone();
|
let ctrl_c = raw_args.ctrl_c.clone();
|
||||||
let ctrl_c = raw_args.ctrl_c.clone();
|
let current_errors = raw_args.current_errors.clone();
|
||||||
let current_errors = raw_args.current_errors.clone();
|
let host = raw_args.host.clone();
|
||||||
let host = raw_args.host.clone();
|
let tag = raw_args.call_info.name_tag.clone();
|
||||||
let tag = raw_args.call_info.name_tag.clone();
|
let (EnterArgs { location, encoding }, _) = raw_args.process(®istry).await?;
|
||||||
let (EnterArgs { location, encoding }, _) = raw_args.process(®istry).await?;
|
let location_string = location.display().to_string();
|
||||||
let location_string = location.display().to_string();
|
let location_clone = location_string.clone();
|
||||||
let location_clone = location_string.clone();
|
|
||||||
|
|
||||||
if location_string.starts_with("help") {
|
if location_string.starts_with("help") {
|
||||||
let spec = location_string.split(':').collect::<Vec<&str>>();
|
let spec = location_string.split(':').collect::<Vec<&str>>();
|
||||||
|
|
||||||
if spec.len() == 2 {
|
if spec.len() == 2 {
|
||||||
let (_, command) = (spec[0], spec[1]);
|
let (_, command) = (spec[0], spec[1]);
|
||||||
|
|
||||||
if registry.has(command) {
|
if registry.has(command) {
|
||||||
yield Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell(
|
return Ok(OutputStream::one(ReturnSuccess::action(
|
||||||
|
CommandAction::EnterHelpShell(
|
||||||
UntaggedValue::string(command).into_value(Tag::unknown()),
|
UntaggedValue::string(command).into_value(Tag::unknown()),
|
||||||
)));
|
),
|
||||||
return;
|
)));
|
||||||
}
|
|
||||||
}
|
|
||||||
yield Ok(ReturnSuccess::Action(CommandAction::EnterHelpShell(
|
|
||||||
UntaggedValue::nothing().into_value(Tag::unknown()),
|
|
||||||
)));
|
|
||||||
} else if location.is_dir() {
|
|
||||||
yield Ok(ReturnSuccess::Action(CommandAction::EnterShell(
|
|
||||||
location_clone,
|
|
||||||
)));
|
|
||||||
} else {
|
|
||||||
// If it's a file, attempt to open the file as a value and enter it
|
|
||||||
let cwd = shell_manager.path();
|
|
||||||
|
|
||||||
let full_path = std::path::PathBuf::from(cwd);
|
|
||||||
|
|
||||||
let (file_extension, contents, contents_tag) =
|
|
||||||
crate::commands::open::fetch(
|
|
||||||
&full_path,
|
|
||||||
&PathBuf::from(location_clone),
|
|
||||||
tag.span,
|
|
||||||
match encoding {
|
|
||||||
Some(e) => e.to_string(),
|
|
||||||
_ => "".to_string()
|
|
||||||
}
|
|
||||||
).await?;
|
|
||||||
|
|
||||||
match contents {
|
|
||||||
UntaggedValue::Primitive(Primitive::String(_)) => {
|
|
||||||
let tagged_contents = contents.into_value(&contents_tag);
|
|
||||||
|
|
||||||
if let Some(extension) = file_extension {
|
|
||||||
let command_name = format!("from {}", extension);
|
|
||||||
if let Some(converter) =
|
|
||||||
registry.get_command(&command_name)
|
|
||||||
{
|
|
||||||
let new_args = RawCommandArgs {
|
|
||||||
host,
|
|
||||||
ctrl_c,
|
|
||||||
current_errors,
|
|
||||||
shell_manager,
|
|
||||||
call_info: UnevaluatedCallInfo {
|
|
||||||
args: nu_protocol::hir::Call {
|
|
||||||
head,
|
|
||||||
positional: None,
|
|
||||||
named: None,
|
|
||||||
span: Span::unknown(),
|
|
||||||
is_last: false,
|
|
||||||
},
|
|
||||||
name_tag: tag.clone(),
|
|
||||||
scope: scope.clone()
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let mut result = converter.run(
|
|
||||||
new_args.with_input(vec![tagged_contents]),
|
|
||||||
®istry,
|
|
||||||
).await;
|
|
||||||
let result_vec: Vec<Result<ReturnSuccess, ShellError>> =
|
|
||||||
result.drain_vec().await;
|
|
||||||
for res in result_vec {
|
|
||||||
match res {
|
|
||||||
Ok(ReturnSuccess::Value(Value {
|
|
||||||
value,
|
|
||||||
..
|
|
||||||
})) => {
|
|
||||||
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(
|
|
||||||
Value {
|
|
||||||
value,
|
|
||||||
tag: contents_tag.clone(),
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
x => yield x,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents)));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let tagged_contents = contents.into_value(contents_tag);
|
|
||||||
|
|
||||||
yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
Ok(OutputStream::one(ReturnSuccess::action(
|
||||||
|
CommandAction::EnterHelpShell(UntaggedValue::nothing().into_value(Tag::unknown())),
|
||||||
|
)))
|
||||||
|
} else if location.is_dir() {
|
||||||
|
Ok(OutputStream::one(ReturnSuccess::action(
|
||||||
|
CommandAction::EnterShell(location_clone),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
// If it's a file, attempt to open the file as a value and enter it
|
||||||
|
let cwd = shell_manager.path();
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
let full_path = std::path::PathBuf::from(cwd);
|
||||||
|
|
||||||
|
let (file_extension, contents, contents_tag) = crate::commands::open::fetch(
|
||||||
|
&full_path,
|
||||||
|
&PathBuf::from(location_clone),
|
||||||
|
tag.span,
|
||||||
|
match encoding {
|
||||||
|
Some(e) => e.to_string(),
|
||||||
|
_ => "".to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
match contents {
|
||||||
|
UntaggedValue::Primitive(Primitive::String(_)) => {
|
||||||
|
let tagged_contents = contents.into_value(&contents_tag);
|
||||||
|
|
||||||
|
if let Some(extension) = file_extension {
|
||||||
|
let command_name = format!("from {}", extension);
|
||||||
|
if let Some(converter) = registry.get_command(&command_name) {
|
||||||
|
let new_args = RawCommandArgs {
|
||||||
|
host,
|
||||||
|
ctrl_c,
|
||||||
|
current_errors,
|
||||||
|
shell_manager,
|
||||||
|
call_info: UnevaluatedCallInfo {
|
||||||
|
args: nu_protocol::hir::Call {
|
||||||
|
head,
|
||||||
|
positional: None,
|
||||||
|
named: None,
|
||||||
|
span: Span::unknown(),
|
||||||
|
is_last: false,
|
||||||
|
},
|
||||||
|
name_tag: tag.clone(),
|
||||||
|
scope: scope.clone(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let mut result = converter
|
||||||
|
.run(new_args.with_input(vec![tagged_contents]), ®istry)
|
||||||
|
.await;
|
||||||
|
let result_vec: Vec<Result<ReturnSuccess, ShellError>> =
|
||||||
|
result.drain_vec().await;
|
||||||
|
|
||||||
|
Ok(futures::stream::iter(result_vec.into_iter().map(
|
||||||
|
move |res| match res {
|
||||||
|
Ok(ReturnSuccess::Value(Value { value, .. })) => Ok(
|
||||||
|
ReturnSuccess::Action(CommandAction::EnterValueShell(Value {
|
||||||
|
value,
|
||||||
|
tag: contents_tag.clone(),
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
x => x,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.to_output_stream())
|
||||||
|
} else {
|
||||||
|
Ok(OutputStream::one(ReturnSuccess::action(
|
||||||
|
CommandAction::EnterValueShell(tagged_contents),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(OutputStream::one(ReturnSuccess::action(
|
||||||
|
CommandAction::EnterValueShell(tagged_contents),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let tagged_contents = contents.into_value(contents_tag);
|
||||||
|
|
||||||
|
Ok(OutputStream::one(ReturnSuccess::action(
|
||||||
|
CommandAction::EnterValueShell(tagged_contents),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -25,14 +25,10 @@ impl WholeStreamCommand for From {
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
let stream = async_stream! {
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
yield Ok(ReturnSuccess::Value(
|
UntaggedValue::string(crate::commands::help::get_help(&From, ®istry))
|
||||||
UntaggedValue::string(crate::commands::help::get_help(&From, ®istry))
|
.into_value(Tag::unknown()),
|
||||||
.into_value(Tag::unknown()),
|
)))
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -339,6 +339,14 @@ impl Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// View the Value as a Primitive value, if possible
|
||||||
|
pub fn is_primitive(&self) -> bool {
|
||||||
|
match &self.value {
|
||||||
|
UntaggedValue::Primitive(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// View the Value as unsigned 64-bit, if possible
|
/// View the Value as unsigned 64-bit, if possible
|
||||||
pub fn as_u64(&self) -> Result<u64, ShellError> {
|
pub fn as_u64(&self) -> Result<u64, ShellError> {
|
||||||
match &self.value {
|
match &self.value {
|
||||||
|
|
Loading…
Reference in a new issue