azalea_brigadier/builder/
required_argument_builder.rs

1use std::{
2    any::Any,
3    fmt::{self, Debug},
4    sync::Arc,
5};
6
7use super::argument_builder::{ArgumentBuilder, ArgumentBuilderType};
8use crate::{
9    arguments::ArgumentType,
10    context::CommandContext,
11    errors::CommandSyntaxError,
12    string_reader::StringReader,
13    suggestion::{SuggestionProvider, Suggestions, SuggestionsBuilder},
14};
15
16/// An argument node type. The `T` type parameter is the type of the argument,
17/// which can be anything.
18pub struct Argument<S> {
19    pub name: String,
20    parser: Arc<dyn ArgumentType + Send + Sync>,
21    custom_suggestions: Option<Arc<dyn SuggestionProvider<S> + Send + Sync>>,
22}
23impl<S> Argument<S> {
24    pub fn new(
25        name: &str,
26        parser: Arc<dyn ArgumentType + Send + Sync>,
27        custom_suggestions: Option<Arc<dyn SuggestionProvider<S> + Send + Sync>>,
28    ) -> Self {
29        Self {
30            name: name.to_string(),
31            parser,
32            custom_suggestions,
33        }
34    }
35
36    pub fn parse(&self, reader: &mut StringReader) -> Result<Arc<dyn Any>, CommandSyntaxError> {
37        self.parser.parse(reader)
38    }
39
40    pub fn list_suggestions(
41        &self,
42        context: CommandContext<S>,
43        builder: SuggestionsBuilder,
44    ) -> Suggestions {
45        if let Some(s) = &self.custom_suggestions {
46            s.get_suggestions(context, builder)
47        } else {
48            self.parser.list_suggestions(builder)
49        }
50    }
51
52    pub fn examples(&self) -> Vec<String> {
53        self.parser.examples()
54    }
55}
56
57impl<S> From<Argument<S>> for ArgumentBuilderType<S> {
58    fn from(argument: Argument<S>) -> Self {
59        Self::Argument(argument)
60    }
61}
62
63impl<S> Debug for Argument<S> {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        f.debug_struct("Argument")
66            .field("name", &self.name)
67            // .field("parser", &self.parser)
68            .finish()
69    }
70}
71
72/// Shortcut for creating a new argument builder node.
73pub fn argument<S>(
74    name: &str,
75    parser: impl ArgumentType + Send + Sync + 'static,
76) -> ArgumentBuilder<S> {
77    ArgumentBuilder::new(Argument::new(name, Arc::new(parser), None).into())
78}
79
80impl<S> Clone for Argument<S> {
81    fn clone(&self) -> Self {
82        Self {
83            name: self.name.clone(),
84            parser: self.parser.clone(),
85            custom_suggestions: self.custom_suggestions.clone(),
86        }
87    }
88}