mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-17 14:29:46 +02: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
|
- name: Install yaak CLI
|
||||||
run: go install github.com/yaakapp/yaakcli@latest
|
run: go install github.com/yaakapp/yaakcli@latest
|
||||||
|
|
||||||
|
- name: Rust test
|
||||||
|
working-directory: src-tauri
|
||||||
|
run: cargo test --all
|
||||||
|
|
||||||
- name: Run lint
|
- name: Run lint
|
||||||
run: npm run lint
|
run: npm run lint
|
||||||
|
|
||||||
|
|||||||
3
src-tauri/Cargo.lock
generated
3
src-tauri/Cargo.lock
generated
@@ -5999,6 +5999,9 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "templates"
|
name = "templates"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tendril"
|
name = "tendril"
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ mod render;
|
|||||||
mod tauri_plugin_mac_window;
|
mod tauri_plugin_mac_window;
|
||||||
mod updates;
|
mod updates;
|
||||||
mod window_menu;
|
mod window_menu;
|
||||||
|
mod template_fns;
|
||||||
|
|
||||||
const DEFAULT_WINDOW_WIDTH: f64 = 1100.0;
|
const DEFAULT_WINDOW_WIDTH: f64 = 1100.0;
|
||||||
const DEFAULT_WINDOW_HEIGHT: f64 = 600.0;
|
const DEFAULT_WINDOW_HEIGHT: f64 = 600.0;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::SystemTime;
|
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use sqlx::types::{Json, JsonValue};
|
use sqlx::types::{Json, JsonValue};
|
||||||
|
|
||||||
|
use templates::parse_and_render;
|
||||||
|
|
||||||
use crate::models::{
|
use crate::models::{
|
||||||
Environment, EnvironmentVariable, HttpRequest, HttpRequestHeader, HttpUrlParameter, Workspace,
|
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 {
|
pub fn render_request(r: &HttpRequest, w: &Workspace, e: Option<&Environment>) -> HttpRequest {
|
||||||
let r = r.clone();
|
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))
|
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 {
|
match name {
|
||||||
"timestamp" => {
|
"timestamp" => timestamp(args),
|
||||||
let now = SystemTime::now();
|
_ => Err(format!("Unknown template function {name}")),
|
||||||
let now: DateTime<Utc> = now.into();
|
|
||||||
now.to_rfc3339()
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
"".to_string()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
log = "0.4.22"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
use crate::{FnArg, Parser, Token, Val};
|
||||||
|
use log::warn;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{FnArg, Parser, Token, Val};
|
type TemplateCallback = fn(name: &str, args: HashMap<String, String>) -> Result<String, String>;
|
||||||
|
|
||||||
type TemplateCallback = fn(name: &str, args: HashMap<String, String>) -> String;
|
|
||||||
|
|
||||||
pub fn parse_and_render(
|
pub fn parse_and_render(
|
||||||
template: &str,
|
template: &str,
|
||||||
@@ -61,7 +61,13 @@ fn render_tag(val: Val, vars: &HashMap<String, String>, cb: Option<TemplateCallb
|
|||||||
})
|
})
|
||||||
.collect::<HashMap<String, String>>();
|
.collect::<HashMap<String, String>>();
|
||||||
match cb {
|
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(),
|
None => "".into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,8 +118,13 @@ mod tests {
|
|||||||
let template = r#"${[ say_hello(a="John", b="Kate") ]}"#;
|
let template = r#"${[ say_hello(a="John", b="Kate") ]}"#;
|
||||||
let result = r#"say_hello: 2, Some("John") Some("Kate")"#;
|
let result = r#"say_hello: 2, Some("John") Some("Kate")"#;
|
||||||
|
|
||||||
fn cb(name: &str, args: HashMap<String, String>) -> String {
|
fn cb(name: &str, args: HashMap<String, String>) -> Result<String, String> {
|
||||||
format!("{name}: {}, {:?} {:?}", args.len(), args.get("a"), args.get("b"))
|
Ok(format!(
|
||||||
|
"{name}: {}, {:?} {:?}",
|
||||||
|
args.len(),
|
||||||
|
args.get("a"),
|
||||||
|
args.get("b")
|
||||||
|
))
|
||||||
}
|
}
|
||||||
assert_eq!(parse_and_render(template, &vars, Some(cb)), result);
|
assert_eq!(parse_and_render(template, &vars, Some(cb)), result);
|
||||||
}
|
}
|
||||||
@@ -123,12 +134,27 @@ mod tests {
|
|||||||
let vars = HashMap::new();
|
let vars = HashMap::new();
|
||||||
let template = r#"${[ upper(foo=secret()) ]}"#;
|
let template = r#"${[ upper(foo=secret()) ]}"#;
|
||||||
let result = r#"ABC"#;
|
let result = r#"ABC"#;
|
||||||
fn cb(name: &str, args: HashMap<String, String>) -> String {
|
fn cb(name: &str, args: HashMap<String, String>) -> Result<String, String> {
|
||||||
match name {
|
Ok(match name {
|
||||||
"secret" => "abc".to_string(),
|
"secret" => "abc".to_string(),
|
||||||
"upper" => args["foo"].to_string().to_uppercase(),
|
"upper" => args["foo"].to_string().to_uppercase(),
|
||||||
_ => "".to_string(),
|
_ => "".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!(
|
assert_eq!(
|
||||||
|
|||||||
Reference in New Issue
Block a user