Refactor: introduce general operate commands to reduce duplicate code (#6879)

* make format filesize more flexible

* make code simpler

* finish refactor on bytes commands

* finish refactor on str commands

* fimplify code

* rename from column_paths to cell_paths
This commit is contained in:
WindSoilder
2022-10-30 05:29:46 +08:00
committed by GitHub
parent 843d8c2242
commit 457514590d
27 changed files with 902 additions and 1126 deletions

View File

@ -22,10 +22,22 @@ pub use upcase::SubCommand as StrUpcase;
use nu_engine::CallExt;
use crate::input_handler::{operate as general_operate, CmdArgument};
use nu_protocol::ast::{Call, CellPath};
use nu_protocol::engine::{EngineState, Stack};
use nu_protocol::{PipelineData, ShellError, Span, Value};
struct Arguments<F: Fn(&str) -> String + Send + Sync + 'static> {
case_operation: &'static F,
cell_paths: Option<Vec<CellPath>>,
}
impl<F: Fn(&str) -> String + Send + Sync + 'static> CmdArgument for Arguments<F> {
fn take_cell_paths(&mut self) -> Option<Vec<CellPath>> {
self.cell_paths.take()
}
}
pub fn operate<F>(
engine_state: &EngineState,
stack: &mut Stack,
@ -36,35 +48,20 @@ pub fn operate<F>(
where
F: Fn(&str) -> String + Send + Sync + 'static,
{
let head = call.head;
let column_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
input.map(
move |v| {
if column_paths.is_empty() {
action(&v, case_operation, head)
} else {
let mut ret = v;
for path in &column_paths {
let r = ret.update_cell_path(
&path.members,
Box::new(move |old| action(old, case_operation, head)),
);
if let Err(error) = r {
return Value::Error { error };
}
}
ret
}
},
engine_state.ctrlc.clone(),
)
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths);
let args = Arguments {
case_operation,
cell_paths,
};
general_operate(action, args, input, call.head, engine_state.ctrlc.clone())
}
pub fn action<F>(input: &Value, case_operation: &F, head: Span) -> Value
fn action<F>(input: &Value, args: &Arguments<F>, head: Span) -> Value
where
F: Fn(&str) -> String + Send + Sync + 'static,
{
let case_operation = args.case_operation;
match input {
Value::String { val, .. } => Value::String {
val: case_operation(val),