use crate::{context::CommandContext, modifier::RedirectModifier, tree::CommandNode}; use super::{literal_argument_builder::Literal, required_argument_builder::Argument}; use std::{cell::RefCell, fmt::Debug, rc::Rc}; #[derive(Debug, Clone)] pub enum ArgumentBuilderType { Literal(Literal), Argument(Argument), } /// A node that hasn't yet been built. pub struct ArgumentBuilder { arguments: CommandNode, command: Option) -> i32>>, requirement: Rc) -> bool>, target: Option>>>, forks: bool, modifier: Option>>, } impl Clone for ArgumentBuilder { fn clone(&self) -> Self { Self { arguments: self.arguments.clone(), command: self.command.clone(), requirement: self.requirement.clone(), target: self.target.clone(), forks: self.forks, modifier: self.modifier.clone(), } } } /// A node that isn't yet built. impl ArgumentBuilder { pub fn new(value: ArgumentBuilderType) -> Self { Self { arguments: CommandNode { value, ..Default::default() }, command: None, requirement: Rc::new(|_| true), forks: false, modifier: None, target: None, } } pub fn then(&mut self, argument: ArgumentBuilder) -> Self { self.then_built(argument.build()) } pub fn then_built(&mut self, argument: CommandNode) -> Self { self.arguments.add_child(&Rc::new(RefCell::new(argument))); self.clone() } pub fn executes(&mut self, f: F) -> Self where F: Fn(&CommandContext) -> i32 + 'static, { self.command = Some(Rc::new(f)); self.clone() } pub fn requires(&mut self, requirement: F) -> Self where F: Fn(Rc) -> bool + 'static, { self.requirement = Rc::new(requirement); self.clone() } pub fn redirect(&mut self, target: Rc>>) -> Self { self.forward(target, None, false) } pub fn fork( &mut self, target: Rc>>, modifier: Rc>, ) -> Self { self.forward(target, Some(modifier), true) } pub fn forward( &mut self, target: Rc>>, modifier: Option>>, fork: bool, ) -> Self { if !self.arguments.children.is_empty() { panic!("Cannot forward a node with children"); } self.target = Some(target); self.modifier = modifier; self.forks = fork; self.clone() } pub fn build(self) -> CommandNode { let mut result = CommandNode { value: self.arguments.value, command: self.command, requirement: self.requirement, redirect: self.target, modifier: self.modifier, forks: self.forks, arguments: Default::default(), children: Default::default(), literals: Default::default(), }; for argument in self.arguments.children.values() { result.add_child(argument); } result } } impl Debug for ArgumentBuilder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ArgumentBuilder") .field("arguments", &self.arguments) // .field("command", &self.command) // .field("requirement", &self.requirement) .field("target", &self.target) .field("forks", &self.forks) // .field("modifier", &self.modifier) .finish() } }