2019-05-29 04:02:36 +00:00
|
|
|
use crate::errors::ShellError;
|
|
|
|
use crate::object::Value;
|
2019-06-22 03:43:37 +00:00
|
|
|
use crate::parser::Span;
|
2019-05-29 04:02:36 +00:00
|
|
|
use crate::prelude::*;
|
|
|
|
|
2019-07-08 16:44:53 +00:00
|
|
|
fn get_member(path: &str, span: Span, 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-06-15 17:52:55 +00:00
|
|
|
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-06-05 01:53:38 +00:00
|
|
|
pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
2019-06-22 03:43:37 +00:00
|
|
|
if args.len() == 0 {
|
2019-06-15 18:36:17 +00:00
|
|
|
return Err(ShellError::maybe_labeled_error(
|
|
|
|
"Get requires a field or field path",
|
|
|
|
"needs parameter",
|
|
|
|
args.name_span,
|
|
|
|
));
|
2019-05-29 04:02:36 +00:00
|
|
|
}
|
|
|
|
|
2019-06-22 03:43:37 +00:00
|
|
|
let amount = args.expect_nth(0)?.as_i64();
|
2019-06-11 06:26:03 +00:00
|
|
|
|
|
|
|
// If it's a number, get the row instead of the column
|
|
|
|
if let Ok(amount) = amount {
|
|
|
|
return Ok(args
|
|
|
|
.input
|
2019-07-03 20:31:15 +00:00
|
|
|
.values
|
2019-06-11 06:26:03 +00:00
|
|
|
.skip(amount as u64)
|
|
|
|
.take(1)
|
2019-07-03 20:31:15 +00:00
|
|
|
.from_input_stream());
|
2019-06-11 06:26:03 +00:00
|
|
|
}
|
|
|
|
|
2019-06-15 17:52:55 +00:00
|
|
|
let fields: Result<Vec<(String, Span)>, _> = args
|
2019-06-22 03:43:37 +00:00
|
|
|
.positional_iter()
|
2019-06-15 17:52:55 +00:00
|
|
|
.map(|a| (a.as_string().map(|x| (x, a.span))))
|
|
|
|
.collect();
|
2019-06-22 20:46:16 +00:00
|
|
|
|
2019-05-29 04:02:36 +00:00
|
|
|
let fields = fields?;
|
|
|
|
|
|
|
|
let stream = args
|
|
|
|
.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-06-15 17:52:55 +00:00
|
|
|
match get_member(&field.0, field.1, &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-03 20:31:15 +00:00
|
|
|
Err(_) => {}
|
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
|
|
|
}
|