use crate::prelude::*; use crate::errors::ShellError; use crate::object::config; use crate::object::Value; use crate::parser::registry::{CommandConfig, NamedType, NamedValue}; use indexmap::IndexMap; use log::trace; use std::iter::FromIterator; pub struct Config; impl Command for Config { fn run(&self, args: CommandArgs) -> Result { config(args) } fn name(&self) -> &str { "config" } fn config(&self) -> CommandConfig { let mut named: IndexMap = IndexMap::new(); named.insert("set".to_string(), NamedType::Optional(NamedValue::Single)); named.insert("get".to_string(), NamedType::Optional(NamedValue::Single)); named.insert("clear".to_string(), NamedType::Switch); named.insert( "remove".to_string(), NamedType::Optional(NamedValue::Single), ); CommandConfig { name: self.name().to_string(), positional: vec![], rest_positional: false, named, is_sink: true, is_filter: false, } } } pub fn config(args: CommandArgs) -> Result { let mut result = crate::object::config::config(args.name_span)?; trace!("{:#?}", args.args.positional); trace!("{:#?}", args.args.named); if let Some(v) = args.get("get") { let key = v.as_string()?; let value = result .get(&key) .ok_or_else(|| ShellError::string(&format!("Missing key {} in config", key)))?; return Ok( stream![value.clone()].into(), // futures::stream::once(futures::future::ready(ReturnSuccess::Value(value.clone()))).into(), ); } if let Some(v) = args.get("set") { if let Ok((key, value)) = v.as_pair() { result.insert(key.as_string()?.to_string(), value.clone()); config::write_config(&result)?; return Ok( stream![Spanned::from_item(Value::Object(result.into()), v.span())] .from_input_stream(), ); } } if let Some(c) = args.get("clear") { result.clear(); config::write_config(&result)?; return Ok( stream![Spanned::from_item(Value::Object(result.into()), c.span())].from_input_stream(), ); } if let Some(v) = args.get("remove") { let key = v.as_string()?; if result.contains_key(&key) { result.remove(&key); } else { return Err(ShellError::string(&format!( "{} does not exist in config", key ))); } let obj = VecDeque::from_iter(vec![Value::Object(result.into()).spanned(v)]); return Ok(obj.from_input_stream()); } if args.len() == 0 { return Ok(vec![Value::Object(result.into()).spanned(args.name_span)].into()); } Err(ShellError::string(format!("Unimplemented"))) }