Skip to content

Commit

Permalink
Added core::Channel and menu functionality. core::Channel may leak me…
Browse files Browse the repository at this point in the history
…mory.
  • Loading branch information
bicarlsen committed Aug 2, 2024
1 parent aa3a64a commit f2eb0e7
Show file tree
Hide file tree
Showing 9 changed files with 397 additions and 13 deletions.
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ version = "0.2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
derive_more = "0.99.18"
futures = { version = "0.3.30", optional = true }
js-sys = "0.3.69"
log = "0.4.21"
Expand All @@ -24,10 +25,11 @@ wasm-bindgen-test = "0.3.42"
all-features = true

[features]
all = ["core", "dpi", "event", "window"]
all = ["core", "dpi", "event", "menu", "window"]
core = []
dpi = []
event = ["dep:futures"]
menu = ["core", "window"]
window = ["dpi", "event"]

[workspace]
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ fn main() {
All modules are gated by accordingly named Cargo features. It is recommended you keep this synced with the features enabled in your [Tauri Allowlist] but no automated tool for this exists (yet).

- **all**: Enables all modules.
- **core**: Enables the `core` module. (Only `invoke` and `convertFileSrc` currently implemented.)
- **core**: Enables the `core` module. (~70% implmented)
- **event**: Enables the `event` module.
- **menu**: Enables the `menu` module. (~20% implemented)
- **window**: Enables the `windows` module. (~20% implemented)

## Are we Tauri yet?
Expand All @@ -64,7 +65,7 @@ These API bindings are not completely on-par with `@tauri-apps/api` yet, but her
- [x] `dpi`
- [x] `event`
- [ ] `image`
- [ ] `menu`
- [x] `menu` (partial implementation)
- [ ] `mocks`
- [ ] `path`
- [ ] `tray`
Expand Down
6 changes: 5 additions & 1 deletion src/core.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// tauri/tooling/api/src/core.ts
function transformCallback(callback, once = false) {
return window.__TAURI_INTERNALS__.transformCallback(callback, once)
}
async function invoke(cmd, args = {}) {
// NB: `options` ignored as not used here.
return window.__TAURI_INTERNALS__.invoke(cmd, args)
Expand All @@ -8,5 +11,6 @@ function convertFileSrc(filePath, protocol = 'asset') {
}
export {
invoke,
convertFileSrc
convertFileSrc,
transformCallback,
}
64 changes: 61 additions & 3 deletions src/core.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! Common functionality
use std::path::PathBuf;
use std::collections::HashMap;

use serde::{de::DeserializeOwned, Serialize};
use futures::{channel::mpsc, future::FusedFuture, Stream, StreamExt};
use serde::{de::DeserializeOwned, ser::SerializeStruct, Serialize};
use serde_wasm_bindgen as swb;
use wasm_bindgen::{prelude::Closure, JsValue};

pub async fn invoke<T>(command: &str, args: impl Serialize) -> T
where
Expand Down Expand Up @@ -38,8 +40,62 @@ pub fn convert_file_src_with_protocol(
.unwrap()
}

// TODO: Could cause memory leak because handler is never released.
#[derive(Debug)]
pub struct Channel<T> {
id: usize,
rx: mpsc::UnboundedReceiver<T>,
}

impl<T> Channel<T> {
pub fn new() -> Self
where
T: DeserializeOwned + 'static,
{
let (tx, rx) = mpsc::unbounded::<T>();
let closure = Closure::<dyn FnMut(JsValue)>::new(move |raw| {
let _ = tx.unbounded_send(serde_wasm_bindgen::from_value(raw).unwrap());
});

let id = inner::transform_callback(&closure, false);
closure.forget();

Channel { id, rx }
}

pub fn id(&self) -> usize {
self.id
}
}

impl<T> Serialize for Channel<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut map = serializer.serialize_struct("Channel", 2)?;
map.serialize_field("__TAURI_CHANNEL_MARKER__", &true)?;
map.serialize_field("id", &self.id)?;
map.end()
}
}

impl<T> Stream for Channel<T> {
type Item = T;

fn poll_next(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Self::Item>> {
self.rx.poll_next_unpin(cx)
}
}

mod inner {
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
use wasm_bindgen::{
prelude::{wasm_bindgen, Closure},
JsValue,
};

#[wasm_bindgen(module = "/src/core.js")]
extern "C" {
Expand All @@ -48,5 +104,7 @@ mod inner {
pub async fn invoke_result(cmd: &str, args: JsValue) -> Result<JsValue, JsValue>;
#[wasm_bindgen(js_name = "convertFileSrc")]
pub fn convert_file_src(filePath: &str, protocol: &str) -> JsValue;
#[wasm_bindgen(js_name = "transformCallback")]
pub fn transform_callback(callback: &Closure<dyn FnMut(JsValue)>, once: bool) -> usize;
}
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ pub mod core;
#[cfg(feature = "dpi")]
pub mod dpi;

#[cfg(feature = "menu")]
pub mod menu;

#[cfg(feature = "window")]
pub mod window;

Expand Down
Empty file added src/menu.js
Empty file.
Loading

0 comments on commit f2eb0e7

Please sign in to comment.