mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 05:14:44 +02:00
move common tools from nu-command
to nu-cmd-base
(#9455)
related to - https://github.com/nushell/nushell/pull/9404 # Description to support our cratification effort and moving non-1.0 commands outside of the main focus, this PR - creates a new `nu-cmd-base` crate to hold the common structs, traits and functions used by all command-related crates - to start the transition, moves the `input_handler` module from `nu-command` to `nu-cmd-base` # User-Facing Changes ``` $nothing ``` # Tests + Formatting - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - ⚫ `toolkit test` - ⚫ `toolkit test stdlib` # After Submitting ``` $nothing ```
This commit is contained in:
90
crates/nu-cmd-base/src/input_handler.rs
Normal file
90
crates/nu-cmd-base/src/input_handler.rs
Normal file
@ -0,0 +1,90 @@
|
||||
use nu_protocol::ast::CellPath;
|
||||
use nu_protocol::{PipelineData, ShellError, Span, Value};
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait CmdArgument {
|
||||
fn take_cell_paths(&mut self) -> Option<Vec<CellPath>>;
|
||||
}
|
||||
|
||||
/// Arguments with only cell_path.
|
||||
///
|
||||
/// If commands is going to use `operate` function, and it only required optional cell_paths
|
||||
/// Using this to simplify code.
|
||||
pub struct CellPathOnlyArgs {
|
||||
cell_paths: Option<Vec<CellPath>>,
|
||||
}
|
||||
|
||||
impl CmdArgument for CellPathOnlyArgs {
|
||||
fn take_cell_paths(&mut self) -> Option<Vec<CellPath>> {
|
||||
self.cell_paths.take()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<CellPath>> for CellPathOnlyArgs {
|
||||
fn from(cell_paths: Vec<CellPath>) -> Self {
|
||||
Self {
|
||||
cell_paths: (!cell_paths.is_empty()).then_some(cell_paths),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple wrapper for `PipelineData::map` method.
|
||||
///
|
||||
/// In detail, for each elements, invoking relative `cmd` with `arg`.
|
||||
///
|
||||
/// If `arg` tell us that its cell path is not None, only map over data under these columns.
|
||||
/// Else it will apply each column inside a table.
|
||||
///
|
||||
/// The validation of input element should be handle by `cmd` itself.
|
||||
pub fn operate<C, A>(
|
||||
cmd: C,
|
||||
mut arg: A,
|
||||
input: PipelineData,
|
||||
span: Span,
|
||||
ctrlc: Option<Arc<AtomicBool>>,
|
||||
) -> Result<PipelineData, ShellError>
|
||||
where
|
||||
A: CmdArgument + Send + Sync + 'static,
|
||||
C: Fn(&Value, &A, Span) -> Value + Send + Sync + 'static + Clone + Copy,
|
||||
{
|
||||
match arg.take_cell_paths() {
|
||||
None => input.map(
|
||||
move |v| {
|
||||
match v {
|
||||
// Propagate errors inside the input
|
||||
Value::Error { .. } => v,
|
||||
_ => cmd(&v, &arg, span),
|
||||
}
|
||||
},
|
||||
ctrlc,
|
||||
),
|
||||
Some(column_paths) => {
|
||||
let arg = Arc::new(arg);
|
||||
input.map(
|
||||
move |mut v| {
|
||||
for path in &column_paths {
|
||||
let opt = arg.clone();
|
||||
let r = v.update_cell_path(
|
||||
&path.members,
|
||||
Box::new(move |old| {
|
||||
match old {
|
||||
// Propagate errors inside the input
|
||||
Value::Error { .. } => old.clone(),
|
||||
_ => cmd(old, &opt, span),
|
||||
}
|
||||
}),
|
||||
);
|
||||
if let Err(error) = r {
|
||||
return Value::Error {
|
||||
error: Box::new(error),
|
||||
};
|
||||
}
|
||||
}
|
||||
v
|
||||
},
|
||||
ctrlc,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
1
crates/nu-cmd-base/src/lib.rs
Normal file
1
crates/nu-cmd-base/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod input_handler;
|
Reference in New Issue
Block a user