mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-01-18 23:16:59 +01:00
Template function return Result
This commit is contained in:
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -83,6 +83,10 @@ jobs:
|
||||
- name: Install yaak CLI
|
||||
run: go install github.com/yaakapp/yaakcli@latest
|
||||
|
||||
- name: Rust test
|
||||
working-directory: src-tauri
|
||||
run: cargo test --all
|
||||
|
||||
- name: Run lint
|
||||
run: npm run lint
|
||||
|
||||
|
||||
3
src-tauri/Cargo.lock
generated
3
src-tauri/Cargo.lock
generated
@@ -5999,6 +5999,9 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "templates"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tendril"
|
||||
|
||||
@@ -70,6 +70,7 @@ mod render;
|
||||
mod tauri_plugin_mac_window;
|
||||
mod updates;
|
||||
mod window_menu;
|
||||
mod template_fns;
|
||||
|
||||
const DEFAULT_WINDOW_WIDTH: f64 = 1100.0;
|
||||
const DEFAULT_WINDOW_HEIGHT: f64 = 600.0;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use std::collections::HashMap;
|
||||
use std::time::SystemTime;
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
use sqlx::types::{Json, JsonValue};
|
||||
|
||||
use templates::parse_and_render;
|
||||
|
||||
use crate::models::{
|
||||
Environment, EnvironmentVariable, HttpRequest, HttpRequestHeader, HttpUrlParameter, Workspace,
|
||||
};
|
||||
use templates::parse_and_render;
|
||||
use crate::template_fns::timestamp;
|
||||
|
||||
pub fn render_request(r: &HttpRequest, w: &Workspace, e: Option<&Environment>) -> HttpRequest {
|
||||
let r = r.clone();
|
||||
@@ -107,16 +108,10 @@ pub fn render(template: &str, vars: &HashMap<String, String>) -> String {
|
||||
parse_and_render(template, vars, Some(template_callback))
|
||||
}
|
||||
|
||||
fn template_callback(name: &str, _args: HashMap<String, String>) -> String {
|
||||
fn template_callback(name: &str, args: HashMap<String, String>) -> Result<String, String> {
|
||||
match name {
|
||||
"timestamp" => {
|
||||
let now = SystemTime::now();
|
||||
let now: DateTime<Utc> = now.into();
|
||||
now.to_rfc3339()
|
||||
},
|
||||
_ => {
|
||||
"".to_string()
|
||||
}
|
||||
"timestamp" => timestamp(args),
|
||||
_ => Err(format!("Unknown template function {name}")),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
64
src-tauri/src/template_fns.rs
Normal file
64
src-tauri/src/template_fns.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn timestamp(args: HashMap<String, String>) -> Result<String, String> {
|
||||
let from = args.get("from").map(|v| v.as_str()).unwrap_or("now");
|
||||
let format = args.get("format").map(|v| v.as_str()).unwrap_or("rfc3339");
|
||||
|
||||
let dt = match from {
|
||||
"now" => {
|
||||
let now = Utc::now();
|
||||
now
|
||||
}
|
||||
_ => {
|
||||
let json_from = serde_json::to_string(from).unwrap_or_default();
|
||||
let now: DateTime<Utc> = serde_json::from_str(json_from.as_str()).unwrap();
|
||||
now
|
||||
}
|
||||
};
|
||||
|
||||
let result = match format {
|
||||
"rfc3339" => dt.to_rfc3339(),
|
||||
"unix" => dt.timestamp().to_string(),
|
||||
"unix_millis" => dt.timestamp_millis().to_string(),
|
||||
_ => "".to_string(),
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// Test it
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::template_fns::timestamp;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[test]
|
||||
fn timestamp_empty() {
|
||||
let args = HashMap::new();
|
||||
assert_ne!(timestamp(args), Ok("".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn timestamp_from() {
|
||||
let mut args = HashMap::new();
|
||||
args.insert("from".to_string(), "2024-07-31T14:16:41.983Z".to_string());
|
||||
assert_eq!(timestamp(args), Ok("2024-07-31T14:16:41.983+00:00".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn timestamp_format_unix() {
|
||||
let mut args = HashMap::new();
|
||||
args.insert("from".to_string(), "2024-07-31T14:16:41.983Z".to_string());
|
||||
args.insert("format".to_string(), "unix".to_string());
|
||||
assert_eq!(timestamp(args), Ok("1722435401".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn timestamp_format_unix_millis() {
|
||||
let mut args = HashMap::new();
|
||||
args.insert("from".to_string(), "2024-07-31T14:16:41.983Z".to_string());
|
||||
args.insert("format".to_string(), "unix_millis".to_string());
|
||||
assert_eq!(timestamp(args), Ok("1722435401983".to_string()));
|
||||
}
|
||||
}
|
||||
@@ -4,3 +4,4 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.22"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::{FnArg, Parser, Token, Val};
|
||||
use log::warn;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{FnArg, Parser, Token, Val};
|
||||
|
||||
type TemplateCallback = fn(name: &str, args: HashMap<String, String>) -> String;
|
||||
type TemplateCallback = fn(name: &str, args: HashMap<String, String>) -> Result<String, String>;
|
||||
|
||||
pub fn parse_and_render(
|
||||
template: &str,
|
||||
@@ -61,7 +61,13 @@ fn render_tag(val: Val, vars: &HashMap<String, String>, cb: Option<TemplateCallb
|
||||
})
|
||||
.collect::<HashMap<String, String>>();
|
||||
match cb {
|
||||
Some(cb) => cb(name.as_str(), resolved_args),
|
||||
Some(cb) => match cb(name.as_str(), resolved_args.clone()) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
warn!("Failed to run template callback {}({:?}): {}", name, resolved_args, e);
|
||||
"".to_string()
|
||||
}
|
||||
},
|
||||
None => "".into(),
|
||||
}
|
||||
}
|
||||
@@ -112,8 +118,13 @@ mod tests {
|
||||
let template = r#"${[ say_hello(a="John", b="Kate") ]}"#;
|
||||
let result = r#"say_hello: 2, Some("John") Some("Kate")"#;
|
||||
|
||||
fn cb(name: &str, args: HashMap<String, String>) -> String {
|
||||
format!("{name}: {}, {:?} {:?}", args.len(), args.get("a"), args.get("b"))
|
||||
fn cb(name: &str, args: HashMap<String, String>) -> Result<String, String> {
|
||||
Ok(format!(
|
||||
"{name}: {}, {:?} {:?}",
|
||||
args.len(),
|
||||
args.get("a"),
|
||||
args.get("b")
|
||||
))
|
||||
}
|
||||
assert_eq!(parse_and_render(template, &vars, Some(cb)), result);
|
||||
}
|
||||
@@ -123,12 +134,27 @@ mod tests {
|
||||
let vars = HashMap::new();
|
||||
let template = r#"${[ upper(foo=secret()) ]}"#;
|
||||
let result = r#"ABC"#;
|
||||
fn cb(name: &str, args: HashMap<String, String>) -> String {
|
||||
match name {
|
||||
fn cb(name: &str, args: HashMap<String, String>) -> Result<String, String> {
|
||||
Ok(match name {
|
||||
"secret" => "abc".to_string(),
|
||||
"upper" => args["foo"].to_string().to_uppercase(),
|
||||
_ => "".to_string(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
parse_and_render(template, &vars, Some(cb)),
|
||||
result.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_fn_err() {
|
||||
let vars = HashMap::new();
|
||||
let template = r#"${[ error() ]}"#;
|
||||
let result = r#""#;
|
||||
fn cb(_name: &str, _args: HashMap<String, String>) -> Result<String, String> {
|
||||
Err("Failed to do it!".to_string())
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user