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