nu_protocol/engine/
command.rs1use serde::{Deserialize, Serialize};
2
3use super::{EngineState, Stack, StateWorkingSet};
4use crate::{
5 Alias, BlockId, DeprecationEntry, DynamicCompletionCallRef, DynamicSuggestion, Example,
6 OutDest, PipelineData, ShellError, Signature, Value, engine::Call,
7};
8use std::{borrow::Cow, fmt::Display};
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum ArgType<'a> {
12 Flag(Cow<'a, str>),
13 Positional(usize),
14}
15
16impl<'a> Display for ArgType<'a> {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 match self {
19 ArgType::Flag(flag_name) => match flag_name {
20 Cow::Borrowed(v) => write!(f, "{v}"),
21 Cow::Owned(v) => write!(f, "{v}"),
22 },
23 ArgType::Positional(idx) => write!(f, "{idx}"),
24 }
25 }
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
29pub enum CommandType {
30 Builtin,
31 Custom,
32 Keyword,
33 External,
34 Alias,
35 Plugin,
36}
37
38impl Display for CommandType {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 let str = match self {
41 CommandType::Builtin => "built-in",
42 CommandType::Custom => "custom",
43 CommandType::Keyword => "keyword",
44 CommandType::External => "external",
45 CommandType::Alias => "alias",
46 CommandType::Plugin => "plugin",
47 };
48 write!(f, "{str}")
49 }
50}
51
52pub trait Command: Send + Sync + CommandClone {
53 fn name(&self) -> &str;
54
55 fn signature(&self) -> Signature;
56
57 fn description(&self) -> &str;
61
62 fn extra_description(&self) -> &str {
66 ""
67 }
68
69 fn run(
70 &self,
71 engine_state: &EngineState,
72 stack: &mut Stack,
73 call: &Call,
74 input: PipelineData,
75 ) -> Result<PipelineData, ShellError>;
76
77 #[allow(unused_variables)]
81 fn run_const(
82 &self,
83 working_set: &StateWorkingSet,
84 call: &Call,
85 input: PipelineData,
86 ) -> Result<PipelineData, ShellError> {
87 Err(ShellError::MissingConstEvalImpl { span: call.head })
88 }
89
90 fn examples(&self) -> Vec<Example<'_>> {
91 Vec::new()
92 }
93
94 fn search_terms(&self) -> Vec<&str> {
96 vec![]
97 }
98
99 fn attributes(&self) -> Vec<(String, Value)> {
100 vec![]
101 }
102
103 fn is_const(&self) -> bool {
105 false
106 }
107
108 fn is_sub(&self) -> bool {
110 self.name().contains(' ')
111 }
112
113 fn block_id(&self) -> Option<BlockId> {
115 None
116 }
117
118 fn as_alias(&self) -> Option<&Alias> {
120 None
121 }
122
123 #[cfg(feature = "plugin")]
125 fn plugin_identity(&self) -> Option<&crate::PluginIdentity> {
126 None
127 }
128
129 fn command_type(&self) -> CommandType {
130 CommandType::Builtin
131 }
132
133 fn is_builtin(&self) -> bool {
134 self.command_type() == CommandType::Builtin
135 }
136
137 fn is_custom(&self) -> bool {
138 self.command_type() == CommandType::Custom
139 }
140
141 fn is_keyword(&self) -> bool {
142 self.command_type() == CommandType::Keyword
143 }
144
145 fn is_known_external(&self) -> bool {
146 self.command_type() == CommandType::External
147 }
148
149 fn is_alias(&self) -> bool {
150 self.command_type() == CommandType::Alias
151 }
152
153 fn is_plugin(&self) -> bool {
154 self.command_type() == CommandType::Plugin
155 }
156
157 fn deprecation_info(&self) -> Vec<DeprecationEntry> {
158 vec![]
159 }
160
161 fn pipe_redirection(&self) -> (Option<OutDest>, Option<OutDest>) {
162 (None, None)
163 }
164
165 #[allow(unused_variables)]
176 #[expect(deprecated)]
177 fn get_dynamic_completion(
178 &self,
179 engine_state: &EngineState,
180 stack: &mut Stack,
181 call: DynamicCompletionCallRef,
182 arg_type: &ArgType,
183 _experimental: ExperimentalMarker,
184 ) -> Result<Option<Vec<DynamicSuggestion>>, ShellError> {
185 Ok(None)
186 }
187
188 fn requires_ast_for_arguments(&self) -> bool {
191 false
192 }
193}
194
195pub trait CommandClone {
196 fn clone_box(&self) -> Box<dyn Command>;
197}
198
199impl<T> CommandClone for T
200where
201 T: 'static + Command + Clone,
202{
203 fn clone_box(&self) -> Box<dyn Command> {
204 Box::new(self.clone())
205 }
206}
207
208impl Clone for Box<dyn Command> {
209 fn clone(&self) -> Box<dyn Command> {
210 self.clone_box()
211 }
212}
213
214#[derive(Debug, Clone, Copy, PartialEq, Eq)]
219#[deprecated(note = "this method is very experimental, likely to change")]
220pub struct ExperimentalMarker;