use crate::commands::WholeStreamCommand; use crate::errors::ShellError; use crate::prelude::*; pub struct SortBy; impl WholeStreamCommand for SortBy { fn run( &self, args: CommandArgs, registry: &CommandRegistry, ) -> Result { sort_by(args, registry) } fn name(&self) -> &str { "sort-by" } fn signature(&self) -> Signature { Signature::build("sort-by").switch("reverse") } } fn sort_by(args: CommandArgs, registry: &CommandRegistry) -> Result { let args = args.evaluate_once(registry)?; let (input, args) = args.parts(); let fields: Result, _> = args .positional .iter() .flatten() .map(|a| a.as_string()) .collect(); let fields = fields?; let output = input.values.collect::>(); let reverse = args.has("reverse"); let output = output.map(move |mut vec| { let calc_key = |item: &Tagged| { fields .iter() .map(|f| item.get_data_by_key(f).map(|i| i.clone())) .collect::>>>() }; if reverse { vec.sort_by_cached_key(|item| { std::cmp::Reverse(calc_key(item)) }); } else { vec.sort_by_cached_key(calc_key); } vec.into_iter().collect::>() }); Ok(output.flatten_stream().from_input_stream()) }