Async template functions working

This commit is contained in:
Gregory Schier
2024-08-19 06:21:03 -07:00
parent ec22191409
commit 1fbcfeaa30
32 changed files with 618 additions and 393 deletions

View File

@@ -4,73 +4,77 @@ use std::collections::HashMap;
use yaak_models::models::{
Environment, EnvironmentVariable, HttpRequest, HttpRequestHeader, HttpUrlParameter, Workspace,
};
use yaak_templates::parse_and_render;
use yaak_templates::{parse_and_render, TemplateCallback};
pub fn render_template(template: &str, w: &Workspace, e: Option<&Environment>) -> String {
let vars = &variables_from_environment(w, e);
render(template, vars)
pub async fn render_template(template: &str, w: &Workspace, e: Option<&Environment>) -> String {
let vars = &variables_from_environment(w, e).await;
render(template, vars).await
}
pub fn render_request(r: &HttpRequest, w: &Workspace, e: Option<&Environment>) -> HttpRequest {
pub async fn render_request(
r: &HttpRequest,
w: &Workspace,
e: Option<&Environment>,
) -> HttpRequest {
let r = r.clone();
let vars = &variables_from_environment(w, e);
let vars = &variables_from_environment(w, e).await;
let mut url_parameters = Vec::new();
for p in r.url_parameters {
url_parameters.push(HttpUrlParameter {
enabled: p.enabled,
name: render(p.name.as_str(), vars).await,
value: render(p.value.as_str(), vars).await,
})
}
let mut headers = Vec::new();
for p in r.headers {
headers.push(HttpRequestHeader {
enabled: p.enabled,
name: render(p.name.as_str(), vars).await,
value: render(p.value.as_str(), vars).await,
})
}
let mut body = HashMap::new();
for (k, v) in r.body {
let v = if v.is_string() {
render(v.as_str().unwrap(), vars).await
} else {
v.to_string()
};
body.insert(render(k.as_str(), vars).await, Value::from(v));
}
let mut authentication = HashMap::new();
for (k, v) in r.authentication {
let v = if v.is_string() {
render(v.as_str().unwrap(), vars).await
} else {
v.to_string()
};
authentication.insert(render(k.as_str(), vars).await, Value::from(v));
}
HttpRequest {
url: render(r.url.as_str(), vars),
url_parameters: r
.url_parameters
.iter()
.map(|p| HttpUrlParameter {
enabled: p.enabled,
name: render(p.name.as_str(), vars),
value: render(p.value.as_str(), vars),
})
.collect::<Vec<HttpUrlParameter>>(),
headers: r
.headers
.iter()
.map(|p| HttpRequestHeader {
enabled: p.enabled,
name: render(p.name.as_str(), vars),
value: render(p.value.as_str(), vars),
})
.collect::<Vec<HttpRequestHeader>>(),
body: r
.body
.iter()
.map(|(k, v)| {
let v = if v.is_string() {
render(v.as_str().unwrap(), vars)
} else {
v.to_string()
};
(render(k, vars), Value::from(v))
})
.collect::<HashMap<String, Value>>(),
authentication: r
.authentication
.iter()
.map(|(k, v)| {
let v = if v.is_string() {
render(v.as_str().unwrap(), vars)
} else {
v.to_string()
};
(render(k, vars), Value::from(v))
})
.collect::<HashMap<String, Value>>(),
url: render(r.url.as_str(), vars).await,
url_parameters,
headers,
body,
authentication,
..r
}
}
pub fn recursively_render_variables<'s>(
pub async fn recursively_render_variables<'s>(
m: &HashMap<String, String>,
render_count: usize,
) -> HashMap<String, String> {
let mut did_render = false;
let mut new_map = m.clone();
for (k, v) in m.clone() {
let rendered = render(v.as_str(), m);
let rendered = Box::pin(render(v.as_str(), m)).await;
if rendered != v {
did_render = true
}
@@ -78,13 +82,13 @@ pub fn recursively_render_variables<'s>(
}
if did_render && render_count <= 3 {
new_map = recursively_render_variables(&new_map, render_count + 1);
new_map = Box::pin(recursively_render_variables(&new_map, render_count + 1)).await;
}
new_map
}
pub fn variables_from_environment(
pub async fn variables_from_environment(
workspace: &Workspace,
environment: Option<&Environment>,
) -> HashMap<String, String> {
@@ -95,17 +99,22 @@ pub fn variables_from_environment(
variables = add_variable_to_map(variables, &e.variables);
}
recursively_render_variables(&variables, 0)
recursively_render_variables(&variables, 0).await
}
pub fn render(template: &str, vars: &HashMap<String, String>) -> String {
parse_and_render(template, vars, Some(template_callback))
pub async fn render(template: &str, vars: &HashMap<String, String>) -> String {
parse_and_render(template, vars, &Box::new(PluginTemplateCallback::default())).await
}
fn template_callback(name: &str, args: HashMap<String, String>) -> Result<String, String> {
match name {
"timestamp" => timestamp(args),
_ => Err(format!("Unknown template function {name}")),
#[derive(Default)]
struct PluginTemplateCallback {}
impl TemplateCallback for PluginTemplateCallback {
async fn run(&self, fn_name: &str, args: HashMap<String, String>) -> Result<String, String> {
match fn_name {
"timestamp" => timestamp(args),
_ => Err(format!("Unknown template function {fn_name}")),
}
}
}