use std::{ any::Any, fmt::{self, Debug}, sync::Arc, }; use super::argument_builder::{ArgumentBuilder, ArgumentBuilderType}; use crate::{ arguments::ArgumentType, context::CommandContext, errors::CommandSyntaxError, string_reader::StringReader, suggestion::{SuggestionProvider, Suggestions, SuggestionsBuilder}, }; /// An argument node type. /// /// The `T` type parameter is the type of the argument, which can be anything. pub struct Argument { pub name: String, parser: Arc, custom_suggestions: Option + Send + Sync>>, } impl Argument { pub fn new( name: &str, parser: Arc, custom_suggestions: Option + Send + Sync>>, ) -> Self { Self { name: name.to_owned(), parser, custom_suggestions, } } pub fn parse(&self, reader: &mut StringReader) -> Result, CommandSyntaxError> { self.parser.parse(reader) } pub fn list_suggestions( &self, context: CommandContext, builder: SuggestionsBuilder, ) -> Suggestions { if let Some(s) = &self.custom_suggestions { s.get_suggestions(context, builder) } else { self.parser.list_suggestions(builder) } } pub fn examples(&self) -> Vec { self.parser.examples() } } impl From> for ArgumentBuilderType { fn from(argument: Argument) -> Self { Self::Argument(argument) } } impl Debug for Argument { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Argument") .field("name", &self.name) // .field("parser", &self.parser) .finish() } } /// Shortcut for creating a new argument builder node. pub fn argument( name: &str, parser: impl ArgumentType + Send + Sync + 'static, ) -> ArgumentBuilder { ArgumentBuilder::new(Argument::new(name, Arc::new(parser), None).into()) } impl Clone for Argument { fn clone(&self) -> Self { Self { name: self.name.clone(), parser: self.parser.clone(), custom_suggestions: self.custom_suggestions.clone(), } } }