use serde::Serialize;
use serde_json::Value as JsonValue;
use std::fmt::Display;
pub fn format_callback<T: Into<JsonValue>, S: AsRef<str> + Display>(
function_name: S,
arg: T,
) -> String {
format!(
r#"
if (window["{fn}"]) {{
window["{fn}"]({arg})
}} else {{
console.warn("[TAURI] Couldn't find callback id {fn} in window. This happens when the app is reloaded while Rust is running an asynchronous operation.")
}}
"#,
fn = function_name,
arg = arg.into().to_string()
)
}
pub fn format_callback_result<T: Serialize, E: Serialize>(
result: Result<T, E>,
success_callback: String,
error_callback: String,
) -> crate::Result<String> {
let rpc = match result {
Ok(res) => format_callback(success_callback, serde_json::to_value(res)?),
Err(err) => format_callback(error_callback, serde_json::to_value(err)?),
};
Ok(rpc)
}
#[cfg(test)]
mod test {
use crate::rpc::*;
use quickcheck_macros::quickcheck;
#[quickcheck]
fn qc_formating(f: String, a: String) -> bool {
if f != "" && a != "" {
let fc = format_callback(f.clone(), a.clone());
fc.contains(&format!(
r#"window["{}"]({})"#,
f,
serde_json::Value::String(a),
))
} else {
true
}
}
#[quickcheck]
fn qc_format_res(result: Result<String, String>, c: String, ec: String) -> bool {
let resp = format_callback_result(result.clone(), c.clone(), ec.clone())
.expect("failed to format callback result");
let (function, value) = match result {
Ok(v) => (c, v),
Err(e) => (ec, e),
};
resp.contains(&format!(
r#"window["{}"]({})"#,
function,
serde_json::Value::String(value),
))
}
}