use crate::commands::command::{Sink, SinkCommandArgs}; use crate::parser::{ registry::{Args, CommandConfig, CommandRegistry}, Span, }; use crate::prelude::*; use serde::{Deserialize, Serialize}; use uuid::Uuid; use indexmap::IndexMap; use std::collections::HashMap; use std::error::Error; use std::sync::Arc; #[derive(Clone, Debug, Serialize, Deserialize)] pub enum SpanSource { Url(String), File(String), } #[derive(Clone)] pub struct Context { commands: IndexMap>, sinks: IndexMap>, crate span_sources: HashMap, crate host: Arc>, crate env: Arc>, } impl Context { crate fn basic() -> Result> { Ok(Context { commands: indexmap::IndexMap::new(), sinks: indexmap::IndexMap::new(), span_sources: HashMap::new(), host: Arc::new(Mutex::new(crate::env::host::BasicHost)), env: Arc::new(Mutex::new(Environment::basic()?)), }) } pub fn add_commands(&mut self, commands: Vec>) { for command in commands { self.commands.insert(command.name().to_string(), command); } } pub fn add_sinks(&mut self, sinks: Vec>) { for sink in sinks { self.sinks.insert(sink.name().to_string(), sink); } } pub fn add_span_source(&mut self, uuid: Uuid, span_source: SpanSource) { self.span_sources.insert(uuid, span_source); } crate fn has_sink(&self, name: &str) -> bool { self.sinks.contains_key(name) } crate fn get_sink(&self, name: &str) -> Arc { self.sinks.get(name).unwrap().clone() } crate fn run_sink( &mut self, command: Arc, name_span: Option, args: Args, input: Vec>, ) -> Result<(), ShellError> { let command_args = SinkCommandArgs { ctx: self.clone(), name_span, span_sources: self.span_sources.clone(), args, input, }; command.run(command_args) } pub fn clone_commands(&self) -> indexmap::IndexMap> { self.commands.clone() } crate fn has_command(&self, name: &str) -> bool { self.commands.contains_key(name) } crate fn get_command(&self, name: &str) -> Arc { self.commands.get(name).unwrap().clone() } crate fn run_command( &mut self, command: Arc, name_span: Option, span_sources: HashMap, args: Args, input: InputStream, ) -> Result { let command_args = CommandArgs { host: self.host.clone(), env: self.env.clone(), name_span, span_sources, args, input, }; command.run(command_args) } } impl CommandRegistry for Context { fn get(&self, name: &str) -> Option { self.commands.get(name).map(|c| c.config()) } }