1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
use serde::Serialize; use serde_json::Value as JsonValue; use std::fmt::Display; /// Formats a function name and argument to be evaluated as callback. /// /// # Examples /// ``` /// use tauri_api::rpc::format_callback; /// // callback with a string argument /// let cb = format_callback("callback-function-name", "the string response"); /// assert_eq!(cb, r#"window["callback-function-name"]("the string response")"#); /// ``` /// /// ``` /// use tauri_api::rpc::format_callback; /// use serde::Serialize; /// // callback with JSON argument /// #[derive(Serialize)] /// struct MyResponse { /// value: String /// } /// let cb = format_callback("callback-function-name", serde_json::to_value(&MyResponse { /// value: "some value".to_string() /// }).expect("failed to serialize")); /// assert_eq!(cb, r#"window["callback-function-name"]({"value":"some value"})"#); /// ``` pub fn format_callback<T: Into<JsonValue>, S: AsRef<str> + Display>( function_name: S, arg: T, ) -> String { format!(r#"window["{}"]({})"#, function_name, arg.into().to_string()) } /// Formats a Result type to its Promise response. /// Useful for Promises handling. /// If the Result `is_ok()`, the callback will be the `success_callback` function name and the argument will be the Ok value. /// If the Result `is_err()`, the callback will be the `error_callback` function name and the argument will be the Err value. /// /// * `result` the Result to check /// * `success_callback` the function name of the Ok callback. Usually the `resolve` of the JS Promise. /// * `error_callback` the function name of the Err callback. Usually the `reject` of the JS Promise. /// /// Note that the callback strings are automatically generated by the `promisified` helper. /// /// # Examples /// ``` /// use tauri_api::rpc::format_callback_result; /// let res: Result<u8, &str> = Ok(5); /// let cb = format_callback_result(res, "success_cb".to_string(), "error_cb".to_string()).expect("failed to format"); /// assert_eq!(cb, r#"window["success_cb"](5)"#); /// /// let res: Result<&str, &str> = Err("error message here"); /// let cb = format_callback_result(res, "success_cb".to_string(), "error_cb".to_string()).expect("failed to format"); /// assert_eq!(cb, r#"window["error_cb"]("error message here")"#); /// ``` 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; // check abritrary strings in the format callback function #[quickcheck] fn qc_formating(f: String, a: String) -> bool { // can not accept empty strings if f != "" && a != "" { // call format callback let fc = format_callback(f.clone(), a.clone()); fc == format!(r#"window["{}"]({})"#, f, serde_json::Value::String(a)) } else { true } } // check arbitrary strings in format_callback_result #[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 == format!( r#"window["{}"]({})"#, function, serde_json::Value::String(value), ) } }