Skip to content

Commit

Permalink
allow using objects directly for menu item construction for static menus
Browse files Browse the repository at this point in the history
allows something like:
```javascript
await Menu.new({
  items: [
    { item: 'Copy' },
    { text: 'Something', action: () => console.log('something clicked') },
    {
      id: 'x',
      icon: '/home/lucas/projects/tauri/tauri/examples/.icons/32x32.png',
      text: 'Tauris',
      action: () => console.log('tauri clicked')
    },
    {
      checked: true,
      text: 'chec',
      action: () => console.log('chec clicked')
    },
    {
      text: 'Sub',
      items: [
        {
          item: 'Paste'
        },
        { text: 'subsubsub', action: () => console.log('sub clicked') }
      ]
    }
  ]
})
```
  • Loading branch information
lucasfernog committed Nov 18, 2023
1 parent dcae92e commit d0eeaba
Show file tree
Hide file tree
Showing 8 changed files with 397 additions and 152 deletions.
2 changes: 1 addition & 1 deletion core/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

47 changes: 32 additions & 15 deletions core/tauri/src/ipc/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::{
},
};

use serde::{Deserialize, Serialize, Serializer};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

use crate::{
command,
Expand Down Expand Up @@ -50,6 +50,32 @@ impl Serialize for Channel {
}
}

pub(crate) struct ChannelRef(pub(crate) CallbackFn);

impl ChannelRef {
fn new(value: impl AsRef<str>) -> Option<Self> {
value
.as_ref()
.split_once(IPC_PAYLOAD_PREFIX)
.and_then(|(_prefix, id)| id.parse().ok())
.map(|id| Self(CallbackFn(id)))
}
}

impl<'de> Deserialize<'de> for ChannelRef {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value: String = Deserialize::deserialize(deserializer)?;
ChannelRef::new(&value).ok_or_else(|| {
serde::de::Error::custom(format!(
"invalid channel value `{value}`, expected a string in the `{IPC_PAYLOAD_PREFIX}ID` format"
))
})
}
}

impl Channel {
/// Creates a new channel with the given message handler.
pub fn new<F: Fn(InvokeBody) -> crate::Result<()> + Send + Sync + 'static>(
Expand Down Expand Up @@ -90,17 +116,6 @@ impl Channel {
})
}

pub(crate) fn load_from_ipc<R: Runtime>(
window: Window<R>,
value: impl AsRef<str>,
) -> Option<Self> {
value
.as_ref()
.split_once(IPC_PAYLOAD_PREFIX)
.and_then(|(_prefix, id)| id.parse().ok())
.map(|callback_id| Self::from_ipc(window, CallbackFn(callback_id)))
}

/// The channel identifier.
pub fn id(&self) -> u32 {
self.id
Expand All @@ -121,11 +136,13 @@ impl<'de, R: Runtime> CommandArg<'de, R> for Channel {
let window = command.message.window();
let value: String =
Deserialize::deserialize(command).map_err(|e| crate::Error::InvalidArgs(name, arg, e))?;
Channel::load_from_ipc(window, &value).ok_or_else(|| {
InvokeError::from_anyhow(anyhow::anyhow!(
ChannelRef::new(&value)
.map(|r| Channel::from_ipc(window, r.0))
.ok_or_else(|| {
InvokeError::from_anyhow(anyhow::anyhow!(
"invalid channel value `{value}`, expected a string in the `{IPC_PAYLOAD_PREFIX}ID` format"
))
})
})
}
}

Expand Down
Loading

0 comments on commit d0eeaba

Please sign in to comment.