use parking_lot::RwLock; use super::{ command_context::CommandContext, parsed_command_node::ParsedCommandNode, string_range::StringRange, ParsedArgument, }; use crate::{ command_dispatcher::CommandDispatcher, modifier::RedirectModifier, tree::{Command, CommandNode}, }; use std::{collections::HashMap, fmt::Debug, sync::Arc}; pub struct CommandContextBuilder<'a, S> { pub arguments: HashMap, pub root: Arc>>, pub nodes: Vec>, pub dispatcher: &'a CommandDispatcher, pub source: Arc, pub command: Command, pub child: Option>>, pub range: StringRange, pub modifier: Option>>, pub forks: bool, } impl Clone for CommandContextBuilder<'_, S> { fn clone(&self) -> Self { Self { arguments: self.arguments.clone(), root: self.root.clone(), nodes: self.nodes.clone(), dispatcher: self.dispatcher, source: self.source.clone(), command: self.command.clone(), child: self.child.clone(), range: self.range.clone(), modifier: self.modifier.clone(), forks: self.forks, } } } impl<'a, S> CommandContextBuilder<'a, S> { pub fn new( dispatcher: &'a CommandDispatcher, source: Arc, root_node: Arc>>, start: usize, ) -> Self { Self { arguments: HashMap::new(), root: root_node, source, range: StringRange::at(start), command: None, dispatcher, nodes: vec![], child: None, modifier: None, forks: false, } } pub fn with_command(&mut self, command: &Command) -> &Self { self.command = command.clone(); self } pub fn with_child(&mut self, child: Arc>) -> &Self { self.child = Some(child); self } pub fn with_argument(&mut self, name: &str, argument: ParsedArgument) -> &Self { self.arguments.insert(name.to_string(), argument); self } pub fn with_node(&mut self, node: Arc>>, range: StringRange) -> &Self { self.nodes.push(ParsedCommandNode { node: node.clone(), range: range.clone(), }); self.range = StringRange::encompassing(&self.range, &range); self.modifier = node.read().modifier.clone(); self.forks = node.read().forks; self } pub fn build(&self, input: &str) -> CommandContext { CommandContext { arguments: self.arguments.clone(), root_node: self.root.clone(), nodes: self.nodes.clone(), source: self.source.clone(), command: self.command.clone(), child: self.child.clone().map(|c| Arc::new(c.build(input))), range: self.range.clone(), forks: self.forks, modifier: self.modifier.clone(), input: input.to_string(), } } } impl Debug for CommandContextBuilder<'_, S> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("CommandContextBuilder") // .field("arguments", &self.arguments) .field("root", &self.root) // .field("nodes", &self.nodes) // .field("dispatcher", &self.dispatcher) // .field("source", &self.source) // .field("command", &self.command) .field("child", &self.child) .field("range", &self.range) // .field("modifier", &self.modifier) .field("forks", &self.forks) .finish() } }