nushell/src/commands/get.rs

83 lines
2.2 KiB
Rust
Raw Normal View History

2019-08-02 21:15:07 +02:00
use crate::commands::StaticCommand;
2019-05-29 06:02:36 +02:00
use crate::errors::ShellError;
use crate::object::Value;
use crate::prelude::*;
2019-08-02 21:15:07 +02:00
pub struct Get;
#[derive(Deserialize)]
pub struct GetArgs {
2019-08-09 06:51:21 +02:00
rest: Vec<Tagged<String>>,
2019-08-02 21:15:07 +02:00
}
impl StaticCommand for Get {
fn name(&self) -> &str {
"get"
}
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, get)?.run()
}
fn signature(&self) -> Signature {
Signature::build("get").rest()
}
}
2019-08-09 06:51:21 +02:00
fn get_member(path: &Tagged<String>, obj: &Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
let mut current = obj;
for p in path.split(".") {
match current.get_data_by_key(p) {
Some(v) => current = v,
None => {
2019-08-12 06:11:42 +02:00
// Before we give up, see if they gave us a path that matches a field name by itself
match obj.get_data_by_key(&path.item) {
Some(v) => return Ok(v.clone()),
None => {
return Err(ShellError::labeled_error(
"Unknown field",
"object missing field",
path.span(),
));
}
}
}
}
}
2019-07-08 18:44:53 +02:00
Ok(current.clone())
}
2019-08-02 21:15:07 +02:00
pub fn get(
GetArgs { rest: fields }: GetArgs,
RunnableContext { input, .. }: RunnableContext,
) -> Result<OutputStream, ShellError> {
2019-07-24 00:22:11 +02:00
let stream = input
.values
2019-05-29 06:02:36 +02:00
.map(move |item| {
let mut result = VecDeque::new();
for field in &fields {
2019-08-02 21:15:07 +02:00
match get_member(field, &item) {
2019-08-01 03:58:42 +02:00
Ok(Tagged {
2019-07-08 18:44:53 +02:00
item: Value::List(l),
..
}) => {
2019-05-29 06:02:36 +02:00
for item in l {
2019-07-08 18:44:53 +02:00
result.push_back(ReturnSuccess::value(item.clone()));
2019-05-29 06:02:36 +02:00
}
}
2019-07-08 18:44:53 +02:00
Ok(x) => result.push_back(ReturnSuccess::value(x.clone())),
Err(x) => result.push_back(Err(x)),
2019-05-29 06:02:36 +02:00
}
}
result
})
.flatten();
Ok(stream.to_output_stream())
2019-05-29 06:02:36 +02:00
}