clap_noun_verb/
builder.rs1use crate::error::Result;
7use crate::noun::NounCommand;
8use crate::registry::CommandRegistry;
9use clap::Command;
10
11pub struct CliBuilder {
33 registry: CommandRegistry,
34}
35
36impl CliBuilder {
37 pub fn new() -> Self {
39 Self { registry: CommandRegistry::new() }
40 }
41
42 pub fn name(mut self, name: impl Into<String>) -> Self {
44 self.registry = self.registry.name(name);
45 self
46 }
47
48 pub fn about(mut self, about: impl Into<String>) -> Self {
50 self.registry = self.registry.about(about);
51 self
52 }
53
54 pub fn version(mut self, version: impl Into<String>) -> Self {
56 self.registry = self.registry.version(version);
57 self
58 }
59
60 pub fn global_args(mut self, args: Vec<clap::Arg>) -> Self {
62 self.registry = self.registry.global_args(args);
63 self
64 }
65
66 pub fn auto_validate(mut self, enable: bool) -> Self {
68 self.registry = self.registry.auto_validate(enable);
69 self
70 }
71
72 pub fn noun(mut self, noun: impl NounCommand + 'static) -> Self {
74 self.registry = self.registry.register_noun(noun);
75 self
76 }
77
78 pub fn nouns<I>(mut self, nouns: I) -> Self
80 where
81 I: IntoIterator<Item = Box<dyn NounCommand>>,
82 {
83 self.registry = self.registry.register_nouns(nouns);
84 self
85 }
86
87 pub fn run(self) -> Result<()> {
89 self.registry.run()
90 }
91
92 pub fn run_with_args(self, args: Vec<String>) -> Result<()> {
94 self.registry.run_with_args(args)
95 }
96
97 pub fn build_command(self) -> Command {
99 self.registry.build_command()
100 }
101
102 pub fn registry(self) -> CommandRegistry {
104 self.registry
105 }
106
107 pub fn registry_ref(&self) -> &CommandRegistry {
109 &self.registry
110 }
111
112 pub fn command_structure(&self) -> std::collections::HashMap<String, Vec<String>> {
114 self.registry.command_structure()
115 }
116
117 pub fn has_command(&self, name: &str) -> bool {
119 self.registry.has_noun(name)
120 }
121}
122
123impl Default for CliBuilder {
124 fn default() -> Self {
125 Self::new()
126 }
127}
128
129pub fn run_cli<F>(builder: F) -> Result<()>
131where
132 F: FnOnce(CliBuilder) -> CliBuilder,
133{
134 let cli = CliBuilder::new();
135 let cli = builder(cli);
136 cli.run()
137}
138
139pub fn run_cli_with_args<F>(args: Vec<String>, builder: F) -> Result<()>
141where
142 F: FnOnce(CliBuilder) -> CliBuilder,
143{
144 let cli = CliBuilder::new();
145 let cli = builder(cli);
146 cli.run_with_args(args)
147}
148
149pub fn build_cli<F>(builder: F) -> (Command, std::collections::HashMap<String, Vec<String>>)
151where
152 F: FnOnce(CliBuilder) -> CliBuilder,
153{
154 let cli = CliBuilder::new();
155 let cli = builder(cli);
156 let registry = cli.registry;
157 let command = registry.build_command();
158 let structure = registry.command_structure();
159 (command, structure)
160}
161
162#[macro_export]
183macro_rules! cli_builder {
184 (name: $name:expr, about: $about:expr, nouns: [$($noun:expr),* $(,)?]) => {
185 {
186 let mut builder = $crate::CliBuilder::new()
187 .name($name)
188 .about($about);
189
190 $(
191 builder = builder.noun($noun);
192 )*
193
194 builder
195 }
196 };
197}