use std::path::PathBuf;
use anyhow::Result;
use clap::{Args, ValueEnum};
use libsail::collection::{Indexable, Iterable};
use crate::cli::{Axis, FormatArg};
use crate::input::{Inputs, axis_for, dispatch};
use crate::output::{emit, writer};
#[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]
pub enum Key {
Name,
Size,
}
#[derive(Args)]
pub struct SortArgs {
#[arg(default_value = "-")]
pub input: PathBuf,
#[arg(long, value_enum, default_value = "name")]
pub key: Key,
#[arg(short, long)]
pub reverse: bool,
#[arg(long, value_enum)]
pub by: Option<Axis>,
#[arg(long, value_enum)]
pub format: Option<FormatArg>,
#[arg(short, long)]
pub output: Option<PathBuf>,
}
impl SortArgs {
pub fn run(self) -> Result<()> {
let inputs = Inputs::read(std::slice::from_ref(&self.input), self.format)?;
let entry = &inputs.entries()[0];
let axis = axis_for(inputs.format(), self.by)?;
let out = writer(self.output.as_deref())?;
let (key, reverse) = (self.key, self.reverse);
dispatch!(
inputs.format(),
entry,
axis,
|collection, size, name, write| {
let sorted = collection.sort_by(|a, b| {
let ordering = match key {
Key::Name => name(a).cmp(&name(b)),
Key::Size => size(a).cmp(&size(b)),
};
if reverse {
ordering.reverse()
} else {
ordering
}
});
emit(sorted.iter(), write, out)
}
)
}
}