CommandDispatcher

Struct CommandDispatcher 

Source
pub struct CommandDispatcher<S>
where Self: Sync + Send,
{ pub root: Arc<RwLock<CommandNode<S>>>, /* private fields */ }
Expand description

The root of the command tree. You need to make this to register commands.

let mut subject = CommandDispatcher::<CommandSource>::new();

Fields§

§root: Arc<RwLock<CommandNode<S>>>

Implementations§

Source§

impl<S> CommandDispatcher<S>

Source

pub fn new() -> Self

Examples found in repository?
azalea/examples/testbot/main.rs (line 57)
36async fn main() -> AppExit {
37    let args = parse_args();
38
39    thread::spawn(deadlock_detection_thread);
40
41    let join_address = args.server.clone();
42
43    let mut builder = SwarmBuilder::new()
44        .set_handler(handle)
45        .set_swarm_handler(swarm_handle);
46
47    for username_or_email in &args.accounts {
48        let account = if username_or_email.contains('@') {
49            Account::microsoft(username_or_email).await.unwrap()
50        } else {
51            Account::offline(username_or_email)
52        };
53
54        builder = builder.add_account_with_state(account, State::new());
55    }
56
57    let mut commands = CommandDispatcher::new();
58    register_commands(&mut commands);
59
60    builder
61        .join_delay(Duration::from_millis(100))
62        .set_swarm_state(SwarmState {
63            args,
64            commands: Arc::new(commands),
65        })
66        .start(join_address)
67        .await
68}
Source

pub fn register( &mut self, node: ArgumentBuilder<S>, ) -> Arc<RwLock<CommandNode<S>>>

Add a new node to the root.

subject.register(literal("foo").executes(|_| 42));
Examples found in repository?
azalea/examples/testbot/commands/combat.rs (lines 8-21)
7pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
8    commands.register(
9        literal("killaura").then(argument("enabled", bool()).executes(|ctx: &Ctx| {
10            let enabled = get_bool(ctx, "enabled").unwrap();
11            let source = ctx.source.lock();
12            let bot = source.bot.clone();
13            bot.query_self::<&mut State, _>(|mut state| state.killaura = enabled);
14            source.reply(if enabled {
15                "Enabled killaura"
16            } else {
17                "Disabled killaura"
18            });
19            1
20        })),
21    );
22}
More examples
Hide additional examples
azalea/examples/testbot/commands/movement.rs (lines 15-73)
14pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
15    commands.register(
16        literal("goto")
17            .executes(|ctx: &Ctx| {
18                let source = ctx.source.lock();
19                println!("got goto");
20                // look for the sender
21                let Some(entity) = source.entity() else {
22                    source.reply("I can't see you!");
23                    return 0;
24                };
25                let position = entity.position();
26                source.reply("ok");
27                source
28                    .bot
29                    .start_goto(BlockPosGoal(BlockPos::from(position)));
30                1
31            })
32            .then(literal("xz").then(argument("x", integer()).then(
33                argument("z", integer()).executes(|ctx: &Ctx| {
34                    let source = ctx.source.lock();
35                    let x = get_integer(ctx, "x").unwrap();
36                    let z = get_integer(ctx, "z").unwrap();
37                    println!("goto xz {x} {z}");
38                    source.reply("ok");
39                    source.bot.start_goto(XZGoal { x, z });
40                    1
41                }),
42            )))
43            .then(literal("radius").then(argument("radius", float()).then(
44                argument("x", integer()).then(argument("y", integer()).then(
45                    argument("z", integer()).executes(|ctx: &Ctx| {
46                        let source = ctx.source.lock();
47                        let radius = get_float(ctx, "radius").unwrap();
48                        let x = get_integer(ctx, "x").unwrap();
49                        let y = get_integer(ctx, "y").unwrap();
50                        let z = get_integer(ctx, "z").unwrap();
51                        println!("goto radius {radius}, position: {x} {y} {z}");
52                        source.reply("ok");
53                        source.bot.start_goto(RadiusGoal {
54                            pos: BlockPos::new(x, y, z).center(),
55                            radius,
56                        });
57                        1
58                    }),
59                )),
60            )))
61            .then(argument("x", integer()).then(argument("y", integer()).then(
62                argument("z", integer()).executes(|ctx: &Ctx| {
63                    let source = ctx.source.lock();
64                    let x = get_integer(ctx, "x").unwrap();
65                    let y = get_integer(ctx, "y").unwrap();
66                    let z = get_integer(ctx, "z").unwrap();
67                    println!("goto xyz {x} {y} {z}");
68                    source.reply("ok");
69                    source.bot.start_goto(BlockPosGoal(BlockPos::new(x, y, z)));
70                    1
71                }),
72            ))),
73    );
74
75    commands.register(literal("down").executes(|ctx: &Ctx| {
76        let source = ctx.source.clone();
77        tokio::spawn(async move {
78            let bot = source.lock().bot.clone();
79            let position = BlockPos::from(bot.position());
80            source.lock().reply("mining...");
81            bot.mine(position.down(1)).await;
82            source.lock().reply("done");
83        });
84        1
85    }));
86
87    commands.register(
88        literal("look")
89            .executes(|ctx: &Ctx| {
90                // look for the sender
91                let source = ctx.source.lock();
92                let Some(entity) = source.entity() else {
93                    source.reply("I can't see you!");
94                    return 0;
95                };
96                let eye_position = entity.eye_position();
97                source.bot.look_at(eye_position);
98                1
99            })
100            .then(argument("x", integer()).then(argument("y", integer()).then(
101                argument("z", integer()).executes(|ctx: &Ctx| {
102                    let pos = BlockPos::new(
103                        get_integer(ctx, "x").unwrap(),
104                        get_integer(ctx, "y").unwrap(),
105                        get_integer(ctx, "z").unwrap(),
106                    );
107                    println!("{pos:?}");
108                    let source = ctx.source.lock();
109                    source.bot.look_at(pos.center());
110                    1
111                }),
112            ))),
113    );
114
115    commands.register(
116        literal("walk").then(argument("seconds", float()).executes(|ctx: &Ctx| {
117            let mut seconds = get_float(ctx, "seconds").unwrap();
118            let source = ctx.source.lock();
119            let bot = source.bot.clone();
120
121            if seconds < 0. {
122                bot.walk(WalkDirection::Backward);
123                seconds = -seconds;
124            } else {
125                bot.walk(WalkDirection::Forward);
126            }
127
128            tokio::spawn(async move {
129                tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
130                bot.walk(WalkDirection::None);
131            });
132            source.reply(format!("ok, walking for {seconds} seconds"));
133            1
134        })),
135    );
136    commands.register(
137        literal("sprint").then(argument("seconds", float()).executes(|ctx: &Ctx| {
138            let seconds = get_float(ctx, "seconds").unwrap();
139            let source = ctx.source.lock();
140            let bot = source.bot.clone();
141            bot.sprint(SprintDirection::Forward);
142            tokio::spawn(async move {
143                tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
144                bot.walk(WalkDirection::None);
145            });
146            source.reply(format!("ok, sprinting for {seconds} seconds"));
147            1
148        })),
149    );
150
151    commands.register(literal("north").executes(|ctx: &Ctx| {
152        let source = ctx.source.lock();
153        source.bot.set_direction(180., 0.);
154        source.reply("ok");
155        1
156    }));
157    commands.register(literal("south").executes(|ctx: &Ctx| {
158        let source = ctx.source.lock();
159        source.bot.set_direction(0., 0.);
160        source.reply("ok");
161        1
162    }));
163    commands.register(literal("east").executes(|ctx: &Ctx| {
164        let source = ctx.source.lock();
165        source.bot.set_direction(-90., 0.);
166        source.reply("ok");
167        1
168    }));
169    commands.register(literal("west").executes(|ctx: &Ctx| {
170        let source = ctx.source.lock();
171        source.bot.set_direction(90., 0.);
172        source.reply("ok");
173        1
174    }));
175    commands.register(
176        literal("jump")
177            .executes(|ctx: &Ctx| {
178                let source = ctx.source.lock();
179                source.bot.jump();
180                source.reply("ok");
181                1
182            })
183            .then(argument("enabled", bool()).executes(|ctx: &Ctx| {
184                let jumping = get_bool(ctx, "enabled").unwrap();
185                let source = ctx.source.lock();
186                source.bot.set_jumping(jumping);
187                1
188            })),
189    );
190
191    let sneak = |ctx: &Ctx| {
192        let source = ctx.source.lock();
193        source.bot.set_crouching(!source.bot.crouching());
194        source.reply("ok");
195        1
196    };
197    let sneak_enabled = argument("enabled", bool()).executes(|ctx: &Ctx| {
198        let sneaking = get_bool(ctx, "enabled").unwrap();
199        let source = ctx.source.lock();
200        source.bot.set_crouching(sneaking);
201        1
202    });
203    commands.register(literal("sneak").executes(sneak).then(sneak_enabled.clone()));
204    commands.register(literal("crouch").executes(sneak).then(sneak_enabled));
205
206    commands.register(literal("stop").executes(|ctx: &Ctx| {
207        let source = ctx.source.lock();
208        source.bot.stop_pathfinding();
209        source.reply("ok");
210        *source.state.task.lock() = BotTask::None;
211        1
212    }));
213}
azalea/examples/testbot/commands/debug.rs (lines 26-30)
25pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
26    commands.register(literal("ping").executes(|ctx: &Ctx| {
27        let source = ctx.source.lock();
28        source.reply("pong!");
29        1
30    }));
31
32    commands.register(literal("disconnect").executes(|ctx: &Ctx| {
33        let source = ctx.source.lock();
34        source.bot.disconnect();
35        1
36    }));
37
38    commands.register(literal("whereami").executes(|ctx: &Ctx| {
39        let source = ctx.source.lock();
40        let Some(entity) = source.entity() else {
41            source.reply("You aren't in render distance!");
42            return 0;
43        };
44        let position = entity.position();
45        source.reply(format!(
46            "You are at {}, {}, {}",
47            position.x, position.y, position.z
48        ));
49        1
50    }));
51
52    commands.register(literal("entityid").executes(|ctx: &Ctx| {
53        let source = ctx.source.lock();
54        let Some(entity) = source.entity() else {
55            source.reply("You aren't in render distance!");
56            return 0;
57        };
58        let entity_id = entity.minecraft_id();
59        source.reply(format!(
60            "Your Minecraft ID is {} and your ECS ID is {entity:?}",
61            *entity_id
62        ));
63        1
64    }));
65
66    let whereareyou = |ctx: &Ctx| {
67        let source = ctx.source.lock();
68        let position = source.bot.position();
69        source.reply(format!(
70            "I'm at {}, {}, {}",
71            position.x, position.y, position.z
72        ));
73        1
74    };
75    commands.register(literal("whereareyou").executes(whereareyou));
76    commands.register(literal("pos").executes(whereareyou));
77
78    commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
79        let source = ctx.source.lock();
80        source.reply(format!(
81            "I am {} ({}, {})",
82            source.bot.username(),
83            source.bot.uuid(),
84            source.bot.entity
85        ));
86        1
87    }));
88
89    commands.register(literal("getdirection").executes(|ctx: &Ctx| {
90        let source = ctx.source.lock();
91        let direction = source.bot.direction();
92        source.reply(format!(
93            "I'm looking at {}, {}",
94            direction.y_rot(),
95            direction.x_rot()
96        ));
97        1
98    }));
99
100    commands.register(literal("health").executes(|ctx: &Ctx| {
101        let source = ctx.source.lock();
102
103        let health = source.bot.health();
104        source.reply(format!("I have {health} health"));
105        1
106    }));
107
108    commands.register(literal("lookingat").executes(|ctx: &Ctx| {
109        let source = ctx.source.lock();
110
111        let hit_result = source.bot.hit_result();
112
113        match &hit_result {
114            HitResult::Block(r) => {
115                if r.miss {
116                    source.reply("I'm not looking at anything");
117                    return 0;
118                }
119                let block_pos = r.block_pos;
120                let block = source.bot.world().read().get_block_state(block_pos);
121                source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
122            }
123            HitResult::Entity(r) => {
124                let entity_kind = **source.bot.entity_component::<EntityKindComponent>(r.entity);
125                source.reply(format!(
126                    "I'm looking at {entity_kind} ({:?}) at {}",
127                    r.entity, r.location
128                ));
129            }
130        }
131
132        1
133    }));
134
135    commands.register(literal("getblock").then(argument("x", integer()).then(
136        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
137            let source = ctx.source.lock();
138            let x = get_integer(ctx, "x").unwrap();
139            let y = get_integer(ctx, "y").unwrap();
140            let z = get_integer(ctx, "z").unwrap();
141            println!("getblock xyz {x} {y} {z}");
142            let block_pos = BlockPos::new(x, y, z);
143            let block = source.bot.world().read().get_block_state(block_pos);
144            source.reply(format!("BlockKind at {block_pos} is {block:?}"));
145            1
146        })),
147    )));
148    commands.register(literal("getfluid").then(argument("x", integer()).then(
149        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
150            let source = ctx.source.lock();
151            let x = get_integer(ctx, "x").unwrap();
152            let y = get_integer(ctx, "y").unwrap();
153            let z = get_integer(ctx, "z").unwrap();
154            println!("getfluid xyz {x} {y} {z}");
155            let block_pos = BlockPos::new(x, y, z);
156            let block = source.bot.world().read().get_fluid_state(block_pos);
157            source.reply(format!("Fluid at {block_pos} is {block:?}"));
158            1
159        })),
160    )));
161
162    commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
163        let source = ctx.source.lock();
164        let pathfinder = source.bot.get_component::<Pathfinder>();
165        let Some(pathfinder) = pathfinder else {
166            source.reply("I don't have the Pathfinder component");
167            return 1;
168        };
169        source.reply(format!(
170            "pathfinder.is_calculating: {}",
171            pathfinder.is_calculating
172        ));
173
174        let executing_path = source.bot.get_component::<ExecutingPath>();
175        let Some(executing_path) = executing_path else {
176            source.reply("I'm not executing a path");
177            return 1;
178        };
179        source.reply(format!(
180            "is_path_partial: {}, path.len: {}, queued_path.len: {}",
181            executing_path.is_path_partial,
182            executing_path.path.len(),
183            if let Some(queued) = &executing_path.queued_path {
184                queued.len().to_string()
185            } else {
186                "n/a".to_owned()
187            },
188        ));
189        1
190    }));
191    commands.register(literal("pathfindermoves").executes(|ctx: &Ctx| {
192        let source = ctx.source.lock();
193
194        let Some(entity) = source.entity() else {
195            source.reply("You aren't in render distance!");
196            return 0;
197        };
198        let position = entity.position();
199        let position = BlockPos::from(position);
200
201        let mut edges = Vec::new();
202        let cached_world = CachedWorld::new(source.bot.world(), position);
203        let mining_cache = MiningCache::new(None);
204        let custom_state = CustomPathfinderStateRef::default();
205
206        azalea::pathfinder::moves::default_move(
207            &mut PathfinderCtx {
208                edges: &mut edges,
209                world: &cached_world,
210                mining_cache: &mining_cache,
211                custom_state: &custom_state,
212            },
213            RelBlockPos::from_origin(position, position),
214        );
215
216        if edges.is_empty() {
217            source.reply("No possible moves.");
218        } else {
219            source.reply("Moves:");
220            for (i, edge) in edges.iter().enumerate() {
221                source.reply(format!("{}) {edge:?}", i + 1));
222            }
223        }
224
225        1
226    }));
227
228    commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
229        let source = ctx.source.lock();
230        source.bot.start_use_item();
231        source.reply("Ok!");
232        1
233    }));
234    commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
235        let source = ctx.source.lock();
236        let max_stack_size = source
237            .bot
238            .get_held_item()
239            .get_component::<MaxStackSize>()
240            .map_or(-1, |s| s.count);
241        source.reply(format!("{max_stack_size}"));
242        1
243    }));
244
245    commands.register(literal("dimensions").executes(|ctx: &Ctx| {
246        let source = ctx.source.lock();
247        let bot_dimensions = source.bot.dimensions();
248        source.reply(format!("{bot_dimensions:?}"));
249        1
250    }));
251
252    commands.register(literal("players").executes(|ctx: &Ctx| {
253        let source = ctx.source.lock();
254        let player_entities = source
255            .bot
256            .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
257        let tab_list = source.bot.tab_list();
258        for player_entity in player_entities {
259            let uuid = player_entity.uuid();
260            source.reply(format!(
261                "{} - {} ({:?})",
262                player_entity.id(),
263                tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
264                uuid
265            ));
266        }
267        1
268    }));
269
270    commands.register(literal("enchants").executes(|ctx: &Ctx| {
271        let source = ctx.source.lock();
272        source.bot.with_registry_holder(|r| {
273            let enchants = &r.enchantment;
274            println!("enchants: {enchants:?}");
275        });
276        1
277    }));
278
279    commands.register(literal("attributes").executes(|ctx: &Ctx| {
280        let source = ctx.source.lock();
281        let attributes = source.bot.attributes();
282        println!("attributes: {attributes:?}");
283        1
284    }));
285
286    commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
287        let source = ctx.source.lock();
288
289        source.reply("Ok!");
290
291
292
293        source.bot.disconnect();
294
295        let ecs = source.bot.ecs.clone();
296        thread::spawn(move || {
297            thread::sleep(Duration::from_secs(1));
298            // dump the ecs
299
300            let mut ecs = ecs.write();
301
302            let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
303            let mut report = File::create(&report_path).unwrap();
304
305            let mut query = ecs.query::<EntityRef>();
306            for entity in query.iter(& ecs) {
307                writeln!(report, "Entity: {}", entity.id()).unwrap();
308                let archetype = entity.archetype();
309                let component_count = archetype.component_count();
310
311                let component_names = archetype
312                    .components()
313                    .iter()
314                    .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
315                    .collect::<Vec<_>>();
316                writeln!(
317                    report,
318                    "- {component_count} components: {}",
319                    component_names.join(", ")
320                )
321                .unwrap();
322            }
323
324            writeln!(report).unwrap();
325
326
327            for (info, _) in ecs.iter_resources() {
328                let name = info.name().to_string();
329                writeln!(report, "Resource: {name}").unwrap();
330                // writeln!(report, "- Size: {} bytes",
331                // info.layout().size()).unwrap();
332
333                match name.as_ref() {
334                    "azalea_world::container::Worlds" => {
335                        let worlds = ecs.resource::<Worlds>();
336
337                        for (world_name, world) in &worlds.map {
338                            writeln!(report, "- Name: {world_name}").unwrap();
339                            writeln!(report, "- Reference count: {}", world.strong_count())
340                                .unwrap();
341                            if let Some(world) = world.upgrade() {
342                                let world = world.read();
343                                let strong_chunks = world
344                                    .chunks
345                                    .map
346                                    .iter()
347                                    .filter(|(_, v)| v.strong_count() > 0)
348                                    .count();
349                                writeln!(
350                                    report,
351                                    "- Chunks: {} strongly referenced, {} in map",
352                                    strong_chunks,
353                                    world.chunks.map.len()
354                                )
355                                .unwrap();
356                                writeln!(
357                                    report,
358                                    "- Entities: {}",
359                                    world.entities_by_chunk.len()
360                                )
361                                .unwrap();
362                            }
363                        }
364                    }
365                    "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
366                        let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
367                        writeln!(report, "- Event count: {}", events.len()).unwrap();
368                    }
369                    "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
370                        let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
371                        writeln!(report, "- Event count: {}", events.len()).unwrap();
372                    }
373
374                    _ => {}
375                }
376            }
377
378            println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
379        });
380
381        1
382    }));
383
384    commands.register(literal("exit").executes(|ctx: &Ctx| {
385        let source = ctx.source.lock();
386        source.reply("bye!");
387
388        source.bot.disconnect();
389
390        let source = ctx.source.clone();
391        thread::spawn(move || {
392            thread::sleep(Duration::from_secs(1));
393
394            source
395                .lock()
396                .bot
397                .ecs
398                .write()
399                .write_message(AppExit::Success);
400        });
401
402        1
403    }));
404}
Source

pub fn parse(&self, command: StringReader, source: S) -> ParseResults<'_, S>

Source

pub fn execute( &self, input: impl Into<StringReader>, source: S, ) -> Result<i32, CommandSyntaxError>

Parse and execute the command using the given input and context.

The number returned depends on the command, and may not be of significance.

This is a shortcut for Self::parse and Self::execute_parsed.

Examples found in repository?
azalea/examples/testbot/main.rs (lines 153-160)
121async fn handle(bot: Client, event: azalea::Event, state: State) -> anyhow::Result<()> {
122    let swarm = bot.resource::<SwarmState>();
123
124    match event {
125        azalea::Event::Init => {
126            bot.set_client_information(ClientInformation {
127                view_distance: 32,
128                ..Default::default()
129            });
130            if swarm.args.pathfinder_debug_particles {
131                bot.ecs
132                    .write()
133                    .entity_mut(bot.entity)
134                    .insert(PathfinderDebugParticles);
135            }
136        }
137        azalea::Event::Chat(chat) => {
138            let (Some(username), content) = chat.split_sender_and_content() else {
139                return Ok(());
140            };
141            if username != swarm.args.owner_username {
142                return Ok(());
143            }
144
145            println!("{:?}", chat.message());
146
147            let command = if chat.is_whisper() {
148                Some(content)
149            } else {
150                content.strip_prefix('!').map(|s| s.to_owned())
151            };
152            if let Some(command) = command {
153                match swarm.commands.execute(
154                    command,
155                    Mutex::new(CommandSource {
156                        bot: bot.clone(),
157                        chat: chat.clone(),
158                        state: state.clone(),
159                    }),
160                ) {
161                    Ok(_) => {}
162                    Err(err) => {
163                        eprintln!("{err:?}");
164                        let command_source = CommandSource {
165                            bot,
166                            chat: chat.clone(),
167                            state: state.clone(),
168                        };
169                        command_source.reply(format!("{err:?}"));
170                    }
171                }
172            }
173        }
174        azalea::Event::Tick => {
175            killaura::tick(bot.clone(), state.clone())?;
176
177            let task = *state.task.lock();
178            match task {
179                BotTask::None => {}
180            }
181        }
182        azalea::Event::Login => {
183            println!("Got login event")
184        }
185        _ => {}
186    }
187
188    Ok(())
189}
Source

pub fn add_paths( node: Arc<RwLock<CommandNode<S>>>, result: &mut Vec<Vec<Arc<RwLock<CommandNode<S>>>>>, parents: Vec<Arc<RwLock<CommandNode<S>>>>, )

Source

pub fn get_path(&self, target: CommandNode<S>) -> Vec<String>

Source

pub fn find_node(&self, path: &[&str]) -> Option<Arc<RwLock<CommandNode<S>>>>

Source

pub fn execute_parsed( &self, parse: ParseResults<'_, S>, ) -> Result<i32, CommandSyntaxError>

Executes a given pre-parsed command.

Source

pub fn get_all_usage( &self, node: &CommandNode<S>, source: &S, restricted: bool, ) -> Vec<String>

Source

pub fn get_smart_usage( &self, node: &CommandNode<S>, source: &S, ) -> Vec<(Arc<RwLock<CommandNode<S>>>, String)>

Gets the possible executable commands from a specified node.

You may use Self::root as a target to get usage data for the entire command tree.

Source

pub fn get_completion_suggestions(parse: ParseResults<'_, S>) -> Suggestions

Source

pub fn get_completion_suggestions_with_cursor( parse: ParseResults<'_, S>, cursor: usize, ) -> Suggestions

Trait Implementations§

Source§

impl<S> Default for CommandDispatcher<S>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more