From 3fb174cdc071d5dbfa8d54be442859ae7be69f7b Mon Sep 17 00:00:00 2001 From: Arijit Basu Date: Tue, 25 Oct 2022 20:23:27 +0530 Subject: [PATCH] Allow using -m outside of xplr shell for debugging Also validate the message before passing. --- src/cli.rs | 31 ++++++++++++++++++------------- src/msg/in_/external.rs | 17 +++++++++++------ 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index bf6ced6..c9c9c05 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,5 +1,6 @@ use crate::app; use anyhow::{bail, Context, Result}; +use app::ExternalMsg; use serde_json as json; use std::fs::File; use std::io::{BufRead, BufReader, Write}; @@ -181,19 +182,23 @@ pub fn pipe_msg_in(args: Vec) -> Result<()> { bail!("too many arguments") } - let path = std::env::var("XPLR_PIPE_MSG_IN") - .context("passing messages in only works inside xplr shell")?; - - let delimiter = fs::read(&path)? - .first() - .cloned() - .context("failed to detect delimmiter")?; - - msg.push(delimiter.try_into()?); - File::options() - .append(true) - .open(&path)? - .write_all(msg.as_bytes())?; + // Validate + let mut msg = json::to_string(&ExternalMsg::try_from(msg.as_str())?)?; + + if let Ok(path) = std::env::var("XPLR_PIPE_MSG_IN") { + let delimiter = fs::read(&path)? + .first() + .cloned() + .context("failed to detect delimmiter")?; + + msg.push(delimiter.try_into()?); + File::options() + .append(true) + .open(&path)? + .write_all(msg.as_bytes())?; + } else { + println!("{}", msg); + } Ok(()) } diff --git a/src/msg/in_/external.rs b/src/msg/in_/external.rs index f20532e..cbf6aea 100644 --- a/src/msg/in_/external.rs +++ b/src/msg/in_/external.rs @@ -2,6 +2,8 @@ use crate::{app::Node, input::InputOperation}; use indexmap::IndexSet; use regex::Regex; use serde::{Deserialize, Serialize}; +use serde_json as json; +use serde_yaml as yaml; use std::cmp::Ordering; #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] @@ -1084,17 +1086,20 @@ pub enum ExternalMsg { } impl TryFrom<&str> for ExternalMsg { - type Error = serde_yaml::Error; + type Error = anyhow::Error; fn try_from(value: &str) -> Result { - if value.starts_with('!') { - serde_yaml::from_str(value) + let msg = if let Ok(val) = json::from_str(&value) { + val + } else if value.starts_with('!') { + yaml::from_str(value)? } else if let Some((msg, args)) = value.split_once(' ') { let msg = format!("!{} {}", msg.trim_end_matches(':'), args); - serde_yaml::from_str(&msg) + yaml::from_str(&msg)? } else { - serde_yaml::from_str(value) - } + yaml::from_str(value)? + }; + Ok(msg) } }