2019-08-02 19:15:07 +00:00
|
|
|
use crate::commands::StaticCommand;
|
2019-05-29 04:02:36 +00:00
|
|
|
use crate::errors::ShellError;
|
|
|
|
use crate::object::Value;
|
|
|
|
use crate::prelude::*;
|
|
|
|
|
2019-08-02 19:15:07 +00:00
|
|
|
pub struct Get;
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
pub struct GetArgs {
|
|
|
|
rest: Vec<Spanned<String>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_member(path: &Spanned<String>, obj: &Spanned<Value>) -> Result<Spanned<Value>, ShellError> {
|
2019-05-31 19:15:29 +00:00
|
|
|
let mut current = obj;
|
|
|
|
for p in path.split(".") {
|
|
|
|
match current.get_data_by_key(p) {
|
|
|
|
Some(v) => current = v,
|
|
|
|
None => {
|
2019-07-03 20:31:15 +00:00
|
|
|
return Err(ShellError::labeled_error(
|
2019-06-15 17:52:55 +00:00
|
|
|
"Unknown field",
|
2019-06-15 18:36:17 +00:00
|
|
|
"object missing field",
|
2019-08-02 19:15:07 +00:00
|
|
|
path.span,
|
2019-07-03 20:31:15 +00:00
|
|
|
));
|
2019-05-31 19:15:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-08 16:44:53 +00:00
|
|
|
Ok(current.clone())
|
2019-05-31 19:15:29 +00:00
|
|
|
}
|
|
|
|
|
2019-08-02 19:15:07 +00:00
|
|
|
pub fn get(
|
|
|
|
GetArgs { rest: fields }: GetArgs,
|
|
|
|
RunnableContext { input, .. }: RunnableContext,
|
|
|
|
) -> Result<OutputStream, ShellError> {
|
2019-06-11 06:26:03 +00:00
|
|
|
// If it's a number, get the row instead of the column
|
2019-08-02 19:15:07 +00:00
|
|
|
// if let Some(amount) = amount {
|
|
|
|
// return Ok(input.values.skip(amount as u64).take(1).from_input_stream());
|
|
|
|
// }
|
2019-05-29 04:02:36 +00:00
|
|
|
|
2019-07-23 22:22:11 +00:00
|
|
|
let stream = input
|
2019-07-03 20:31:15 +00:00
|
|
|
.values
|
2019-05-29 04:02:36 +00:00
|
|
|
.map(move |item| {
|
|
|
|
let mut result = VecDeque::new();
|
|
|
|
for field in &fields {
|
2019-08-02 19:15:07 +00:00
|
|
|
match get_member(field, &item) {
|
2019-07-08 16:44:53 +00:00
|
|
|
Ok(Spanned {
|
|
|
|
item: Value::List(l),
|
|
|
|
..
|
|
|
|
}) => {
|
2019-05-29 04:02:36 +00:00
|
|
|
for item in l {
|
2019-07-08 16:44:53 +00:00
|
|
|
result.push_back(ReturnSuccess::value(item.clone()));
|
2019-05-29 04:02:36 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-08 16:44:53 +00:00
|
|
|
Ok(x) => result.push_back(ReturnSuccess::value(x.clone())),
|
2019-07-13 16:59:59 +00:00
|
|
|
Err(x) => result.push_back(Err(x)),
|
2019-05-29 04:02:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result
|
|
|
|
})
|
|
|
|
.flatten();
|
|
|
|
|
2019-07-03 20:31:15 +00:00
|
|
|
Ok(stream.to_output_stream())
|
2019-05-29 04:02:36 +00:00
|
|
|
}
|