From d3b58c9a0eaa7db719ff6bca0db02c2c999eb96a Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 4 Apr 2020 19:40:53 -0400 Subject: [PATCH] Add rust code to invoke the shim --- src/duster/mod.rs | 7 +++++ src/duster/node_invoker.rs | 61 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/duster/node_invoker.rs diff --git a/src/duster/mod.rs b/src/duster/mod.rs index e69de29..fcd5e9b 100644 --- a/src/duster/mod.rs +++ b/src/duster/mod.rs @@ -0,0 +1,7 @@ +//! This module contains a rust implementation of LinkedIn Dust + +mod node_invoker; + +pub use node_invoker::run_node_dust; +pub use node_invoker::NodeError; +pub use node_invoker::Result; diff --git a/src/duster/node_invoker.rs b/src/duster/node_invoker.rs new file mode 100644 index 0000000..c554634 --- /dev/null +++ b/src/duster/node_invoker.rs @@ -0,0 +1,61 @@ +use std::error; +use std::fmt; +use std::io::Write; +use std::process::Output; +use std::process::{Command, Stdio}; + +pub type Result = std::result::Result; + +#[derive(Clone)] +pub struct NodeError { + output: Output, +} + +impl fmt::Display for NodeError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Error from node: {}", + String::from_utf8_lossy(&self.output.stderr) + ) + } +} + +impl fmt::Debug for NodeError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Error from node: {}", + String::from_utf8_lossy(&self.output.stderr) + ) + } +} + +impl error::Error for NodeError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + None + } +} + +/// Invokes Node to run the authentic LinkedIn Dust +pub fn run_node_dust(template_path: &str, context: &str) -> Result { + let mut proc = Command::new("node") + .arg("./src/js/dustjs_shim.js") + .arg(template_path) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("failed to execute process"); + proc.stdin + .take() + .unwrap() + .write_all(context.as_bytes()) + .expect("Failed to write to stdin of node process"); + let output = proc.wait_with_output().expect("Failed to wait on node"); + if output.status.success() { + Ok(String::from_utf8(output.stdout).expect("Invalid UTF-8 from node process")) + } else { + Err(NodeError { output: output }) + } +}