You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.0 KiB
Rust
74 lines
2.0 KiB
Rust
use jsonpath::Selector;
|
|
use lazy_static::lazy_static;
|
|
use regex::{Match, Regex};
|
|
use serde_json::Value;
|
|
|
|
#[derive(Clone)]
|
|
pub struct ActionTemplate {
|
|
src: String,
|
|
matches: Vec<(usize, usize)>,
|
|
}
|
|
|
|
impl ActionTemplate {
|
|
pub fn new<S: ToString>(command: S) -> Self {
|
|
lazy_static! {
|
|
static ref PLACEHOLDER_REGEX: Regex = Regex::new(r"\{\{(.*?)\}\}").unwrap();
|
|
}
|
|
let command = command.to_string();
|
|
let matches = PLACEHOLDER_REGEX
|
|
.find_iter(&command)
|
|
.map(|m: Match| (m.start(), m.end()))
|
|
.collect();
|
|
Self {
|
|
src: command,
|
|
matches,
|
|
}
|
|
}
|
|
|
|
pub fn evaluate(&self, json: &Value) -> String {
|
|
let mut result_string = String::with_capacity(self.src.len());
|
|
let mut last_index = 0;
|
|
|
|
for (start, end) in &self.matches {
|
|
let before = &self.src[last_index..*start];
|
|
let query = &self.src[*start + 2..*end - 2];
|
|
result_string.push_str(before);
|
|
result_string.push_str(&evaluate_path(query, json).unwrap_or_default());
|
|
|
|
last_index = *end;
|
|
}
|
|
result_string.push_str(&self.src[last_index..]);
|
|
|
|
result_string
|
|
}
|
|
}
|
|
|
|
fn evaluate_path(query: &str, json: &Value) -> Option<String> {
|
|
let selector = Selector::new(query).ok()?;
|
|
let results = selector
|
|
.find(json)
|
|
.map(json_to_string)
|
|
.collect::<Vec<String>>();
|
|
|
|
Some(results.join("\n"))
|
|
}
|
|
|
|
fn json_to_string(value: &Value) -> String {
|
|
match value {
|
|
Value::Null => String::with_capacity(0),
|
|
Value::Bool(b) => b.to_string(),
|
|
Value::Number(n) => n.to_string(),
|
|
Value::String(s) => s.to_owned(),
|
|
Value::Array(a) => a
|
|
.iter()
|
|
.map(|v| json_to_string(v))
|
|
.collect::<Vec<String>>()
|
|
.join("\n"),
|
|
Value::Object(o) => o
|
|
.iter()
|
|
.map(|(k, v)| format!("{} = {}", k, json_to_string(v)))
|
|
.collect::<Vec<String>>()
|
|
.join("\n"),
|
|
}
|
|
}
|