2019-05-29 04:02:36 +00:00
|
|
|
use crate::errors::ShellError;
|
|
|
|
use crate::object::Value;
|
2019-06-15 17:52:55 +00:00
|
|
|
use crate::parser::lexer::Span;
|
2019-05-29 04:02:36 +00:00
|
|
|
use crate::prelude::*;
|
|
|
|
|
2019-06-15 17:52:55 +00:00
|
|
|
fn get_member(path: &str, span: Span, obj: &Value) -> Option<Value> {
|
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-06-15 17:52:55 +00:00
|
|
|
return Some(Value::Error(Box::new(ShellError::labeled_error(
|
|
|
|
"Unknown field",
|
|
|
|
"unknown field",
|
|
|
|
span,
|
|
|
|
))));
|
2019-05-31 19:15:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(current.copy())
|
|
|
|
}
|
|
|
|
|
2019-06-05 01:53:38 +00:00
|
|
|
pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
2019-06-07 22:35:07 +00:00
|
|
|
if args.positional.len() == 0 {
|
|
|
|
if let Some(span) = args.name_span {
|
|
|
|
return Err(ShellError::labeled_error(
|
|
|
|
"Get requires a field or field path",
|
|
|
|
"needs parameter",
|
|
|
|
span,
|
|
|
|
));
|
|
|
|
} else {
|
|
|
|
return Err(ShellError::string("get requires fields."));
|
|
|
|
}
|
2019-05-29 04:02:36 +00:00
|
|
|
}
|
|
|
|
|
2019-06-11 06:26:03 +00:00
|
|
|
let amount = args.positional[0].as_i64();
|
|
|
|
|
|
|
|
// If it's a number, get the row instead of the column
|
|
|
|
if let Ok(amount) = amount {
|
|
|
|
return Ok(args
|
|
|
|
.input
|
|
|
|
.skip(amount as u64)
|
|
|
|
.take(1)
|
|
|
|
.map(|v| ReturnValue::Value(v))
|
|
|
|
.boxed());
|
|
|
|
}
|
|
|
|
|
2019-06-15 17:52:55 +00:00
|
|
|
let fields: Result<Vec<(String, Span)>, _> = args
|
|
|
|
.positional
|
|
|
|
.iter()
|
|
|
|
.map(|a| (a.as_string().map(|x| (x, a.span))))
|
|
|
|
.collect();
|
2019-05-29 04:02:36 +00:00
|
|
|
let fields = fields?;
|
|
|
|
|
|
|
|
let stream = args
|
|
|
|
.input
|
|
|
|
.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-05-29 04:02:36 +00:00
|
|
|
Some(Value::List(l)) => {
|
|
|
|
for item in l {
|
|
|
|
result.push_back(ReturnValue::Value(item.copy()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(x) => result.push_back(ReturnValue::Value(x.copy())),
|
|
|
|
None => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result
|
|
|
|
})
|
|
|
|
.flatten();
|
|
|
|
|
|
|
|
Ok(stream.boxed())
|
|
|
|
}
|