brush_builtins/
factory.rs

1use std::collections::HashMap;
2
3#[allow(clippy::wildcard_imports)]
4use super::*;
5
6#[allow(unused_imports, reason = "not all builtins are used in all configs")]
7use brush_core::builtins::{self, builtin, decl_builtin, raw_arg_builtin, simple_builtin};
8
9/// Identifies well-known sets of builtins.
10#[derive(Clone, Copy, Eq, PartialEq)]
11pub enum BuiltinSet {
12    /// Identifies builtins appropriate for POSIX `sh` compatibility.
13    ShMode,
14    /// Identifies builtins appropriate for a more full-featured `bash`-compatible shell.
15    BashMode,
16}
17
18/// Returns the default set of built-in commands.
19///
20/// # Arguments
21///
22/// * `set` - The set of built-ins to return.
23#[allow(clippy::too_many_lines)]
24pub fn default_builtins(set: BuiltinSet) -> HashMap<String, builtins::Registration> {
25    let mut m = HashMap::<String, builtins::Registration>::new();
26
27    //
28    // POSIX special builtins
29    //
30    // N.B. There seems to be some inconsistency as to whether 'times'
31    // should be a special built-in.
32    //
33
34    #[cfg(feature = "builtin.break")]
35    m.insert("break".into(), builtin::<break_::BreakCommand>().special());
36    #[cfg(feature = "builtin.colon")]
37    m.insert(
38        ":".into(),
39        simple_builtin::<colon::ColonCommand>().special(),
40    );
41    #[cfg(feature = "builtin.continue")]
42    m.insert(
43        "continue".into(),
44        builtin::<continue_::ContinueCommand>().special(),
45    );
46    #[cfg(feature = "builtin.dot")]
47    m.insert(".".into(), builtin::<dot::DotCommand>().special());
48    #[cfg(feature = "builtin.eval")]
49    m.insert("eval".into(), builtin::<eval::EvalCommand>().special());
50    #[cfg(all(feature = "builtin.exec", unix))]
51    m.insert("exec".into(), builtin::<exec::ExecCommand>().special());
52    #[cfg(feature = "builtin.exit")]
53    m.insert("exit".into(), builtin::<exit::ExitCommand>().special());
54    #[cfg(feature = "builtin.export")]
55    m.insert(
56        "export".into(),
57        decl_builtin::<export::ExportCommand>().special(),
58    );
59    #[cfg(feature = "builtin.return")]
60    m.insert(
61        "return".into(),
62        builtin::<return_::ReturnCommand>().special(),
63    );
64    #[cfg(feature = "builtin.set")]
65    m.insert("set".into(), builtin::<set::SetCommand>().special());
66    #[cfg(feature = "builtin.shift")]
67    m.insert("shift".into(), builtin::<shift::ShiftCommand>().special());
68    #[cfg(feature = "builtin.trap")]
69    m.insert("trap".into(), builtin::<trap::TrapCommand>().special());
70    #[cfg(feature = "builtin.unset")]
71    m.insert("unset".into(), builtin::<unset::UnsetCommand>().special());
72
73    #[cfg(feature = "builtin.declare")]
74    m.insert(
75        "readonly".into(),
76        decl_builtin::<declare::DeclareCommand>().special(),
77    );
78    #[cfg(feature = "builtin.times")]
79    m.insert("times".into(), builtin::<times::TimesCommand>().special());
80
81    //
82    // Non-special builtins
83    //
84
85    #[cfg(feature = "builtin.alias")]
86    m.insert("alias".into(), builtin::<alias::AliasCommand>()); // TODO: should be exec_declaration_builtin
87    #[cfg(feature = "builtin.bg")]
88    m.insert("bg".into(), builtin::<bg::BgCommand>());
89    #[cfg(feature = "builtin.cd")]
90    m.insert("cd".into(), builtin::<cd::CdCommand>());
91    #[cfg(feature = "builtin.command")]
92    m.insert("command".into(), builtin::<command::CommandCommand>());
93    #[cfg(feature = "builtin.false")]
94    m.insert("false".into(), builtin::<false_::FalseCommand>());
95    #[cfg(feature = "builtin.fg")]
96    m.insert("fg".into(), builtin::<fg::FgCommand>());
97    #[cfg(feature = "builtin.getopts")]
98    m.insert("getopts".into(), builtin::<getopts::GetOptsCommand>());
99    #[cfg(feature = "builtin.hash")]
100    m.insert("hash".into(), builtin::<hash::HashCommand>());
101    #[cfg(feature = "builtin.help")]
102    m.insert("help".into(), builtin::<help::HelpCommand>());
103    #[cfg(feature = "builtin.jobs")]
104    m.insert("jobs".into(), builtin::<jobs::JobsCommand>());
105    #[cfg(all(feature = "builtin.kill", unix))]
106    m.insert("kill".into(), builtin::<kill::KillCommand>());
107    #[cfg(feature = "builtin.declare")]
108    m.insert("local".into(), decl_builtin::<declare::DeclareCommand>());
109    #[cfg(feature = "builtin.pwd")]
110    m.insert("pwd".into(), builtin::<pwd::PwdCommand>());
111    #[cfg(feature = "builtin.read")]
112    m.insert("read".into(), builtin::<read::ReadCommand>());
113    #[cfg(feature = "builtin.true")]
114    m.insert("true".into(), builtin::<true_::TrueCommand>());
115    #[cfg(feature = "builtin.type")]
116    m.insert("type".into(), builtin::<type_::TypeCommand>());
117    #[cfg(all(feature = "builtin.ulimit", unix))]
118    m.insert("ulimit".into(), builtin::<ulimit::ULimitCommand>());
119    #[cfg(all(feature = "builtin.umask", unix))]
120    m.insert("umask".into(), builtin::<umask::UmaskCommand>());
121    #[cfg(feature = "builtin.unalias")]
122    m.insert("unalias".into(), builtin::<unalias::UnaliasCommand>());
123    #[cfg(feature = "builtin.wait")]
124    m.insert("wait".into(), builtin::<wait::WaitCommand>());
125
126    #[cfg(feature = "builtin.fc")]
127    m.insert("fc".into(), builtin::<fc::FcCommand>());
128
129    if matches!(set, BuiltinSet::BashMode) {
130        #[cfg(feature = "builtin.builtin")]
131        m.insert(
132            "builtin".into(),
133            raw_arg_builtin::<builtin_::BuiltinCommand>(),
134        );
135        #[cfg(feature = "builtin.declare")]
136        m.insert("declare".into(), decl_builtin::<declare::DeclareCommand>());
137        #[cfg(feature = "builtin.echo")]
138        m.insert("echo".into(), builtin::<echo::EchoCommand>());
139        #[cfg(feature = "builtin.enable")]
140        m.insert("enable".into(), builtin::<enable::EnableCommand>());
141        #[cfg(feature = "builtin.let")]
142        m.insert("let".into(), builtin::<let_::LetCommand>());
143        #[cfg(feature = "builtin.mapfile")]
144        m.insert("mapfile".into(), builtin::<mapfile::MapFileCommand>());
145        #[cfg(feature = "builtin.mapfile")]
146        m.insert("readarray".into(), builtin::<mapfile::MapFileCommand>());
147        #[cfg(all(feature = "builtin.printf", any(unix, windows)))]
148        m.insert("printf".into(), builtin::<printf::PrintfCommand>());
149        #[cfg(feature = "builtin.shopt")]
150        m.insert("shopt".into(), builtin::<shopt::ShoptCommand>());
151        #[cfg(feature = "builtin.dot")]
152        m.insert("source".into(), builtin::<dot::DotCommand>().special());
153        #[cfg(all(feature = "builtin.suspend", unix))]
154        m.insert("suspend".into(), builtin::<suspend::SuspendCommand>());
155        #[cfg(feature = "builtin.test")]
156        m.insert("test".into(), builtin::<test::TestCommand>());
157        #[cfg(feature = "builtin.test")]
158        m.insert("[".into(), builtin::<test::TestCommand>());
159        #[cfg(feature = "builtin.declare")]
160        m.insert("typeset".into(), decl_builtin::<declare::DeclareCommand>());
161
162        // Completion builtins
163        #[cfg(feature = "builtin.complete")]
164        m.insert("complete".into(), builtin::<complete::CompleteCommand>());
165        #[cfg(feature = "builtin.compgen")]
166        m.insert("compgen".into(), builtin::<complete::CompGenCommand>());
167        #[cfg(feature = "builtin.compopt")]
168        m.insert("compopt".into(), builtin::<complete::CompOptCommand>());
169
170        // Dir stack builtins
171        #[cfg(feature = "builtin.dirs")]
172        m.insert("dirs".into(), builtin::<dirs::DirsCommand>());
173        #[cfg(feature = "builtin.popd")]
174        m.insert("popd".into(), builtin::<popd::PopdCommand>());
175        #[cfg(feature = "builtin.pushd")]
176        m.insert("pushd".into(), builtin::<pushd::PushdCommand>());
177
178        // Input configuration builtins
179        #[cfg(feature = "builtin.bind")]
180        m.insert("bind".into(), builtin::<bind::BindCommand>());
181
182        // History
183        #[cfg(feature = "builtin.history")]
184        m.insert("history".into(), builtin::<history::HistoryCommand>());
185
186        // TODO: implement caller builtin
187        m.insert("caller".into(), builtin::<unimp::UnimplementedCommand>());
188
189        // TODO: implement disown builtin
190        m.insert("disown".into(), builtin::<unimp::UnimplementedCommand>());
191
192        // TODO: implement logout builtin
193        m.insert("logout".into(), builtin::<unimp::UnimplementedCommand>());
194    }
195
196    //
197    // Brush-specific builtins.
198    //
199    #[cfg(feature = "builtin.brushinfo")]
200    m.insert("brushinfo".into(), builtin::<brushinfo::BrushInfoCommand>());
201
202    m
203}