feat(core) add cargo examples (#499)

* add cargo example

* change name to communication

* update scripts to set environment vars for example

* remove build key
This commit is contained in:
Tensor-Programming 2020-03-09 02:26:07 -04:00 committed by GitHub
parent 20b70ce38f
commit 4e76f42d8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 606 additions and 7 deletions

View File

@ -8,8 +8,8 @@ IF "%cd%\"=="%~dp0" (
)
rem setup relative paths from root folder
set "TAURI_DIST_DIR=%~1tauri\test\fixture\dist"
set "TAURI_DIR=%~1tauri\test\fixture\src-tauri"
set "TAURI_DIST_DIR=%~1tauri\examples\communication\dist"
set "TAURI_DIR=%~1tauri\examples\communication\src-tauri"
rem convert relative path to absolute path and re-set it into the enviroment var
for /F "delims=" %%F IN ("%TAURI_DIST_DIR%") DO SET "TAURI_DIST_DIR=%%~fF"
for /F "delims=" %%F IN ("%TAURI_DIR%") DO SET "TAURI_DIR=%%~fF"

View File

@ -1,7 +1,7 @@
Write-Output "Setting up enviromental Variables"
# setup relative paths
$dist_path = "tauri\test\fixture\dist"
$src_path = "tauri\test\fixture\src-tauri"
$dist_path = "tauri\examples\communication\dist"
$src_path = "tauri\examples\communication\src-tauri"
# check to see if path variables are directories
if ((Test-Path $dist_path -PathType Any) -Or (Test-Path $src_path -PathType Any)) {

View File

@ -2,8 +2,8 @@
# Note: Script must be run like this `. .init_env.sh` to setup variables for your current shell
# define relative paths
DistPath='tauri/test/fixture/dist'
SrcPath='tauri/test/fixture/src-tauri'
DistPath='tauri/examples/communication/dist'
SrcPath='tauri/examples/communication/src-tauri'
echo "Setting up enviroment Variables"

View File

@ -31,6 +31,9 @@ tauri_includedir_codegen = "0.5.2"
[dev-dependencies]
proptest = "0.9.5"
serde_json = "1.0"
tauri = {path = ".", features = [ "all-api", "edge" ]}
serde = { version = "1.0", features = [ "derive" ] }
[features]
edge = ["web-view/edge"]
@ -50,5 +53,9 @@ event = []
updater = []
[package.metadata.docs.rs]
features = ["dev-server", "all-api"]
[[example]]
name = "communication"
path = "examples/communication/src-tauri/src/main.rs"
features = ["dev-server", "all-api"]

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<body>
<div>
<button id="log">Call Log API</button>
<button id="request">Call Request (async) API</button>
<button id="event">Send event to Rust</button>
<div id="response"></div>
</div>
<script>
window.onTauriInit = function () {
window.tauri.listen('rust-event', function (res) {
document.getElementById('response').innerHTML = JSON.stringify(res)
})
}
document.getElementById('log').addEventListener('click', function () {
window.tauri.invoke({
cmd: 'logOperation',
event: 'tauri-click',
payload: 'this payload is optional because we used Option in Rust'
})
})
document.getElementById('request').addEventListener('click', function () {
window.tauri.promisified({
cmd: 'performRequest',
endpoint: 'dummy endpoint arg',
body: {
id: 5,
name: 'test'
}
}).then(function (response) {
document.getElementById('response').innerHTML = JSON.stringify(response)
})
})
document.getElementById('event').addEventListener('click', function () {
window.tauri.emit('js-event', 'this is the payload string')
})
</script>
</body>
</html>

View File

@ -0,0 +1,347 @@
<!DOCTYPE html><html><head><meta http-equiv="Content-Security-Policy" content="default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'"></head><body><script>/* eslint-disable */
/**
* * THIS FILE IS GENERATED AUTOMATICALLY.
* DO NOT EDIT.
*
* Please whitelist these API functions in tauri.conf.json
*
**/
/**
* @module tauri
* @description This API interface makes powerful interactions available
* to be run on client side applications. They are opt-in features, and
* must be enabled in tauri.conf.json
*
* Each binding MUST provide these interfaces in order to be compliant,
* and also whitelist them based upon the developer's settings.
*/
// polyfills
if (!String.prototype.startsWith) {
String.prototype.startsWith = function (searchString, position) {
position = position || 0
return this.substr(position, searchString.length) === searchString
}
}
// makes the window.external.invoke API available after window.location.href changes
switch (navigator.platform) {
case "Macintosh":
case "MacPPC":
case "MacIntel":
case "Mac68K":
window.external = this
invoke = function (x) {
webkit.messageHandlers.invoke.postMessage(x);
}
break;
case "Windows":
case "WinCE":
case "Win32":
case "Win64":
break;
default:
window.external = this
invoke = function (x) {
window.webkit.messageHandlers.external.postMessage(x);
}
break;
}
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1)
}
var uid = function () {
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4()
}
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var __reject = function () {
return new Promise(function (_, reject) {
reject();
});
}
window.tauri = {
invoke: function invoke(args) {
window.external.invoke(JSON.stringify(args));
},
listen: function listen(event, handler) {
var once = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
this.invoke({
cmd: 'listen',
event: event,
handler: window.tauri.transformCallback(handler, once),
once: once
});
},
emit: function emit(evt, payload) {
this.invoke({
cmd: 'emit',
event: evt,
payload: payload || ''
});
},
transformCallback: function transformCallback(callback) {
var once = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var identifier = uid();
window[identifier] = function (result) {
if (once) {
delete window[identifier];
}
return callback && callback(result);
};
return identifier;
},
promisified: function promisified(args) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.invoke(_objectSpread({
callback: _this.transformCallback(resolve),
error: _this.transformCallback(reject)
}, args));
});
},
readTextFile: function readTextFile(path) {
return this.promisified({
cmd: 'readTextFile',
path: path
});
},
readBinaryFile: function readBinaryFile(path) {
return this.promisified({
cmd: 'readBinaryFile',
path: path
});
},
writeFile: function writeFile(cfg) {
if (_typeof(cfg) === 'object') {
Object.freeze(cfg);
}
this.invoke({
cmd: 'writeFile',
file: cfg.file,
contents: cfg.contents
});
},
listFiles: function listFiles(path) {
return this.promisified({
cmd: 'listFiles',
path: path
});
},
listDirs: function listDirs(path) {
return this.promisified({
cmd: 'listDirs',
path: path
});
},
setTitle: function setTitle(title) {
this.invoke({
cmd: 'setTitle',
title: title
});
},
open: function open(uri) {
this.invoke({
cmd: 'open',
uri: uri
});
},
execute: function execute(command, args) {
if (_typeof(args) === 'object') {
Object.freeze(args);
}
return this.promisified({
cmd: 'execute',
command: command,
args: typeof args === 'string' ? [args] : args
});
},
bridge: function bridge(command, payload) {
if (_typeof(payload) === 'object') {
Object.freeze(payload);
}
return this.promisified({
cmd: 'bridge',
command: command,
payload: _typeof(payload) === 'object' ? [payload] : payload
});
},
loadAsset: function loadAsset(assetName, assetType) {
return this.promisified({
cmd: 'loadAsset',
asset: assetName,
asset_type: assetType || 'unknown'
})
}
};
// init tauri API
try {
window.tauri.invoke({
cmd: 'init'
})
} catch (e) {
window.addEventListener('DOMContentLoaded', function () {
window.tauri.invoke({
cmd: 'init'
})
}, true)
}
document.addEventListener('error', function (e) {
var target = e.target
while (target != null) {
if (target.matches ? target.matches('img') : target.msMatchesSelector('img')) {
window.tauri.loadAsset(target.src, 'image')
.then(function (img) {
target.src = img
})
break
}
target = target.parentElement
}
}, true)
// open <a href="..."> links with the Tauri API
function __openLinks() {
document.querySelector('body').addEventListener('click', function (e) {
var target = e.target
while (target != null) {
if (target.matches ? target.matches('a') : target.msMatchesSelector('a')) {
if (target.href && target.href.startsWith('http') && target.target === '_blank') {
window.tauri.open(target.href)
e.preventDefault()
}
break
}
target = target.parentElement
}
}, true)
}
if (document.readyState === 'complete' || document.readyState === 'interactive') {
__openLinks()
} else {
window.addEventListener('DOMContentLoaded', function () {
__openLinks()
}, true)
}
</script>
<div>
<button id="log">Call Log API</button>
<button id="request">Call Request (async) API</button>
<button id="event">Send event to Rust</button>
<div id="response"></div>
</div>
<script>
window.onTauriInit = function () {
window.tauri.listen('rust-event', function (res) {
document.getElementById('response').innerHTML = JSON.stringify(res)
})
}
document.getElementById('log').addEventListener('click', function () {
window.tauri.invoke({
cmd: 'logOperation',
event: 'tauri-click',
payload: 'this payload is optional because we used Option in Rust'
})
})
document.getElementById('request').addEventListener('click', function () {
window.tauri.promisified({
cmd: 'performRequest',
endpoint: 'dummy endpoint arg',
body: {
id: 5,
name: 'test'
}
}).then(function (response) {
document.getElementById('response').innerHTML = JSON.stringify(response)
})
})
document.getElementById('event').addEventListener('click', function () {
window.tauri.emit('js-event', 'this is the payload string')
})
</script>
</body></html>

View File

@ -0,0 +1,10 @@
{
"name": "communication-example",
"version": "1.0.0",
"description": "A Tauri example showcasing the JS-Rust communication",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"private": true
}

View File

@ -0,0 +1,11 @@
# Generated by Cargo
# will have compiled files and executables
/target/
WixTools
# These are backup files generated by rustfmt
**/*.rs.bk
tauri.js
config.json
bundle.json

View File

@ -0,0 +1,39 @@
workspace = { }
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = [ "you" ]
license = ""
repository = ""
default-run = "app"
edition = "2018"
build = "src/build.rs"
[package.metadata.bundle]
identifier = "com.tauri.dev"
icon = [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = [ "derive" ] }
tauri = { version = "0.4", features = [ "all-api", "edge" ] }
[target."cfg(windows)".build-dependencies]
winres = "0.1"
[features]
dev-server = [ "tauri/dev-server" ]
embedded-server = [ "tauri/embedded-server" ]
no-server = [ "tauri/no-server" ]
[[bin]]
name = "app"
path = "src/main.rs"

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@ -0,0 +1,13 @@
max_width = 100
hard_tabs = false
tab_spaces = 2
newline_style = "Auto"
use_small_heuristics = "Default"
reorder_imports = true
reorder_modules = true
remove_nested_parens = true
edition = "2018"
merge_derives = true
use_try_shorthand = false
use_field_init_shorthand = false
force_explicit_abi = true

View File

@ -0,0 +1,16 @@
#[cfg(windows)]
extern crate winres;
#[cfg(windows)]
fn main() {
if std::path::Path::new("icons/icon.ico").exists() {
let mut res = winres::WindowsResource::new();
res.set_icon("icons/icon.ico");
res.compile().expect("Unable to find visual studio tools");
} else {
panic!("No Icon.ico found. Please add one or check the path");
}
}
#[cfg(not(windows))]
fn main() {}

View File

@ -0,0 +1,14 @@
use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub struct RequestBody {
id: i32,
name: String
}
#[derive(Deserialize)]
#[serde(tag = "cmd", rename_all = "camelCase")]
pub enum Cmd {
LogOperation { event: String, payload: Option<String> },
PerformRequest { endpoint: String, body: RequestBody, callback: String, error: String },
}

View File

@ -0,0 +1,64 @@
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
mod cmd;
use serde::Serialize;
#[derive(Serialize)]
struct Reply {
data: String
}
fn main() {
tauri::AppBuilder::new()
.setup(|webview, _source| {
let handle = webview.handle();
tauri::event::listen(String::from("js-event"), move |msg| {
println!("got js-event with message '{}'", msg);
let reply = Reply {
data: "something else".to_string(),
};
tauri::event::emit(
&handle,
String::from("rust-event"),
serde_json::to_string(&reply).unwrap(),
);
});
})
.invoke_handler(|_webview, arg| {
use cmd::Cmd::*;
match serde_json::from_str(arg) {
Err(_) => {}
Ok(command) => {
match command {
LogOperation { event, payload } => {
println!("{} {:?}", event, payload);
},
PerformRequest { endpoint, body, callback, error } => {
// tauri::execute_promise is a helper for APIs that uses the tauri.promisified JS function
// so you can easily communicate between JS and Rust with promises
tauri::execute_promise(
_webview,
move || {
println!("{} {:?}", endpoint, body);
// perform an async operation here
// if the returned value is Ok, the promise will be resolved with its value
// if the returned value is Err, the promise will be rejected with its value
// the value is a string that will be eval'd
Ok("{ key: 'response', value: [{ id: 3 }] }".to_string())
},
callback,
error
)
},
}
}
}
})
.build()
.run();
}

View File

@ -0,0 +1,33 @@
{
"build": {
"distDir": "../dist",
"devPath": "../dist"
},
"ctx": {},
"tauri": {
"embeddedServer": {
"active": true
},
"bundle": {
"active": true,
"icon": [
"icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"
]
},
"whitelist": {
"all": true
},
"window": {
"title": "Tauri App"
},
"security": {
"csp": "default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline'"
},
"edge": {
"active": true
},
"inliner": {
"active": true
}
}
}

View File

@ -18,6 +18,7 @@ mod file_system;
mod salt;
#[cfg(feature = "embedded-server")]
mod tcp;
mod view;
use std::process::Stdio;

1
tauri/src/view.rs Normal file
View File

@ -0,0 +1 @@