mirror of
https://github.com/Devolutions/IronRDP.git
synced 2025-07-07 17:45:01 +00:00
fix(web): improve make_bridge! macro hygiene (#777)
There was still some room for improvement.
This commit is contained in:
parent
24e64d7589
commit
194ed07630
5 changed files with 131 additions and 59 deletions
|
@ -4,12 +4,20 @@ pub trait ClipboardData {
|
|||
type Item: ClipboardItem;
|
||||
|
||||
fn create() -> Self;
|
||||
|
||||
fn add_text(&mut self, mime_type: &str, text: &str);
|
||||
|
||||
fn add_binary(&mut self, mime_type: &str, binary: &[u8]);
|
||||
|
||||
fn items(&self) -> &[Self::Item];
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
self.items().is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ClipboardItem {
|
||||
fn mime_type(&self) -> &str;
|
||||
|
||||
fn value(&self) -> impl Into<JsValue>;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use wasm_bindgen::prelude::*;
|
|||
|
||||
pub trait IronError {
|
||||
fn backtrace(&self) -> String;
|
||||
|
||||
fn kind(&self) -> IronErrorKind;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
pub trait DeviceEvent {
|
||||
fn mouse_button_pressed(button: u8) -> Self;
|
||||
|
||||
fn mouse_button_released(button: u8) -> Self;
|
||||
|
||||
fn mouse_move(x: u16, y: u16) -> Self;
|
||||
|
||||
fn wheel_rotations(vertical: bool, rotation_units: i16) -> Self;
|
||||
|
||||
fn key_pressed(scancode: u16) -> Self;
|
||||
|
||||
fn key_released(scancode: u16) -> Self;
|
||||
|
||||
fn unicode_pressed(unicode: char) -> Self;
|
||||
|
||||
fn unicode_released(unicode: char) -> Self;
|
||||
}
|
||||
|
||||
|
@ -13,5 +20,6 @@ pub trait InputTransaction {
|
|||
type DeviceEvent: DeviceEvent;
|
||||
|
||||
fn create() -> Self;
|
||||
|
||||
fn add_event(&mut self, event: Self::DeviceEvent);
|
||||
}
|
||||
|
|
|
@ -37,11 +37,6 @@ pub trait RemoteDesktopApi {
|
|||
#[macro_export]
|
||||
macro_rules! make_bridge {
|
||||
($api:ty) => {
|
||||
use $crate::{
|
||||
ClipboardData as _, ClipboardItem as _, DeviceEvent as _, InputTransaction as _, IronError as _,
|
||||
Session as _, SessionBuilder as _, SessionTerminationInfo as _,
|
||||
};
|
||||
|
||||
#[$crate::internal::wasm_bindgen::prelude::wasm_bindgen]
|
||||
pub struct Session(<$api as $crate::RemoteDesktopApi>::Session);
|
||||
|
||||
|
@ -126,22 +121,25 @@ macro_rules! make_bridge {
|
|||
#[doc(hidden)]
|
||||
impl Session {
|
||||
pub async fn run(&self) -> Result<SessionTerminationInfo, IronError> {
|
||||
self.0.run().await.map(SessionTerminationInfo).map_err(IronError)
|
||||
$crate::Session::run(&self.0)
|
||||
.await
|
||||
.map(SessionTerminationInfo)
|
||||
.map_err(IronError)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = desktopSize)]
|
||||
pub fn desktop_size(&self) -> $crate::DesktopSize {
|
||||
self.0.desktop_size()
|
||||
$crate::Session::desktop_size(&self.0)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = applyInputs)]
|
||||
pub fn apply_inputs(&self, transaction: InputTransaction) -> Result<(), IronError> {
|
||||
self.0.apply_inputs(transaction.0).map_err(IronError)
|
||||
$crate::Session::apply_inputs(&self.0, transaction.0).map_err(IronError)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = releaseAllInputs)]
|
||||
pub fn release_all_inputs(&self) -> Result<(), IronError> {
|
||||
self.0.release_all_inputs().map_err(IronError)
|
||||
$crate::Session::release_all_inputs(&self.0).map_err(IronError)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = synchronizeLockKeys)]
|
||||
|
@ -152,18 +150,19 @@ macro_rules! make_bridge {
|
|||
caps_lock: bool,
|
||||
kana_lock: bool,
|
||||
) -> Result<(), IronError> {
|
||||
self.0
|
||||
.synchronize_lock_keys(scroll_lock, num_lock, caps_lock, kana_lock)
|
||||
$crate::Session::synchronize_lock_keys(&self.0, scroll_lock, num_lock, caps_lock, kana_lock)
|
||||
.map_err(IronError)
|
||||
}
|
||||
|
||||
pub fn shutdown(&self) -> Result<(), IronError> {
|
||||
self.0.shutdown().map_err(IronError)
|
||||
$crate::Session::shutdown(&self.0).map_err(IronError)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = onClipboardPaste)]
|
||||
pub async fn on_clipboard_paste(&self, content: ClipboardData) -> Result<(), IronError> {
|
||||
self.0.on_clipboard_paste(content.0).await.map_err(IronError)
|
||||
$crate::Session::on_clipboard_paste(&self.0, content.0)
|
||||
.await
|
||||
.map_err(IronError)
|
||||
}
|
||||
|
||||
pub fn resize(
|
||||
|
@ -174,20 +173,26 @@ macro_rules! make_bridge {
|
|||
physical_width: Option<u32>,
|
||||
physical_height: Option<u32>,
|
||||
) {
|
||||
self.0
|
||||
.resize(width, height, scale_factor, physical_width, physical_height);
|
||||
$crate::Session::resize(
|
||||
&self.0,
|
||||
width,
|
||||
height,
|
||||
scale_factor,
|
||||
physical_width,
|
||||
physical_height,
|
||||
);
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = supportsUnicodeKeyboardShortcuts)]
|
||||
pub fn supports_unicode_keyboard_shortcuts(&self) -> bool {
|
||||
self.0.supports_unicode_keyboard_shortcuts()
|
||||
$crate::Session::supports_unicode_keyboard_shortcuts(&self.0)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = extensionCall)]
|
||||
pub fn extension_call(
|
||||
ext: $crate::Extension,
|
||||
) -> Result<$crate::internal::wasm_bindgen::JsValue, IronError> {
|
||||
<<$api as $crate::RemoteDesktopApi>::Session>::extension_call(ext).map_err(IronError)
|
||||
<<$api as $crate::RemoteDesktopApi>::Session as $crate::Session>::extension_call(ext).map_err(IronError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,54 +201,58 @@ macro_rules! make_bridge {
|
|||
impl SessionBuilder {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn create() -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::SessionBuilder>::create())
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::SessionBuilder as $crate::SessionBuilder>::create())
|
||||
}
|
||||
|
||||
pub fn username(&self, username: String) -> Self {
|
||||
Self(self.0.username(username))
|
||||
Self($crate::SessionBuilder::username(&self.0, username))
|
||||
}
|
||||
|
||||
pub fn destination(&self, destination: String) -> Self {
|
||||
Self(self.0.destination(destination))
|
||||
Self($crate::SessionBuilder::destination(&self.0, destination))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = serverDomain)]
|
||||
pub fn server_domain(&self, server_domain: String) -> Self {
|
||||
Self(self.0.server_domain(server_domain))
|
||||
Self($crate::SessionBuilder::server_domain(&self.0, server_domain))
|
||||
}
|
||||
|
||||
pub fn password(&self, password: String) -> Self {
|
||||
Self(self.0.password(password))
|
||||
Self($crate::SessionBuilder::password(&self.0, password))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = proxyAddress)]
|
||||
pub fn proxy_address(&self, address: String) -> Self {
|
||||
Self(self.0.proxy_address(address))
|
||||
Self($crate::SessionBuilder::proxy_address(&self.0, address))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = authToken)]
|
||||
pub fn auth_token(&self, token: String) -> Self {
|
||||
Self(self.0.auth_token(token))
|
||||
Self($crate::SessionBuilder::auth_token(&self.0, token))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = desktopSize)]
|
||||
pub fn desktop_size(&self, desktop_size: $crate::DesktopSize) -> Self {
|
||||
Self(self.0.desktop_size(desktop_size))
|
||||
Self($crate::SessionBuilder::desktop_size(&self.0, desktop_size))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = renderCanvas)]
|
||||
pub fn render_canvas(&self, canvas: $crate::internal::web_sys::HtmlCanvasElement) -> Self {
|
||||
Self(self.0.render_canvas(canvas))
|
||||
Self($crate::SessionBuilder::render_canvas(&self.0, canvas))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = setCursorStyleCallback)]
|
||||
pub fn set_cursor_style_callback(&self, callback: $crate::internal::web_sys::js_sys::Function) -> Self {
|
||||
Self(self.0.set_cursor_style_callback(callback))
|
||||
Self($crate::SessionBuilder::set_cursor_style_callback(
|
||||
&self.0, callback,
|
||||
))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = setCursorStyleCallbackContext)]
|
||||
pub fn set_cursor_style_callback_context(&self, context: $crate::internal::wasm_bindgen::JsValue) -> Self {
|
||||
Self(self.0.set_cursor_style_callback_context(context))
|
||||
Self($crate::SessionBuilder::set_cursor_style_callback_context(
|
||||
&self.0, context,
|
||||
))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = remoteClipboardChangedCallback)]
|
||||
|
@ -251,7 +260,9 @@ macro_rules! make_bridge {
|
|||
&self,
|
||||
callback: $crate::internal::web_sys::js_sys::Function,
|
||||
) -> Self {
|
||||
Self(self.0.remote_clipboard_changed_callback(callback))
|
||||
Self($crate::SessionBuilder::remote_clipboard_changed_callback(
|
||||
&self.0, callback,
|
||||
))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = remoteReceivedFormatListCallback)]
|
||||
|
@ -259,7 +270,9 @@ macro_rules! make_bridge {
|
|||
&self,
|
||||
callback: $crate::internal::web_sys::js_sys::Function,
|
||||
) -> Self {
|
||||
Self(self.0.remote_received_format_list_callback(callback))
|
||||
Self($crate::SessionBuilder::remote_received_format_list_callback(
|
||||
&self.0, callback,
|
||||
))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = forceClipboardUpdateCallback)]
|
||||
|
@ -267,15 +280,20 @@ macro_rules! make_bridge {
|
|||
&self,
|
||||
callback: $crate::internal::web_sys::js_sys::Function,
|
||||
) -> Self {
|
||||
Self(self.0.force_clipboard_update_callback(callback))
|
||||
Self($crate::SessionBuilder::force_clipboard_update_callback(
|
||||
&self.0, callback,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn extension(&self, ext: $crate::Extension) -> Self {
|
||||
Self(self.0.extension(ext))
|
||||
Self($crate::SessionBuilder::extension(&self.0, ext))
|
||||
}
|
||||
|
||||
pub async fn connect(&self) -> Result<Session, IronError> {
|
||||
self.0.connect().await.map(Session).map_err(IronError)
|
||||
$crate::SessionBuilder::connect(&self.0)
|
||||
.await
|
||||
.map(Session)
|
||||
.map_err(IronError)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,7 +301,7 @@ macro_rules! make_bridge {
|
|||
#[doc(hidden)]
|
||||
impl SessionTerminationInfo {
|
||||
pub fn reason(&self) -> String {
|
||||
self.0.reason()
|
||||
$crate::SessionTerminationInfo::reason(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,48 +310,57 @@ macro_rules! make_bridge {
|
|||
impl DeviceEvent {
|
||||
#[wasm_bindgen(js_name = mouseButtonPressed)]
|
||||
pub fn mouse_button_pressed(button: u8) -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent>::mouse_button_pressed(button))
|
||||
Self(
|
||||
<<$api as $crate::RemoteDesktopApi>::DeviceEvent as $crate::DeviceEvent>::mouse_button_pressed(
|
||||
button,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = mouseButtonReleased)]
|
||||
pub fn mouse_button_released(button: u8) -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent>::mouse_button_released(button))
|
||||
Self(
|
||||
<<$api as $crate::RemoteDesktopApi>::DeviceEvent as $crate::DeviceEvent>::mouse_button_released(
|
||||
button,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = mouseMove)]
|
||||
pub fn mouse_move(x: u16, y: u16) -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent>::mouse_move(
|
||||
x, y,
|
||||
))
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent as $crate::DeviceEvent>::mouse_move(x, y))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = wheelRotations)]
|
||||
pub fn wheel_rotations(vertical: bool, rotation_units: i16) -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent>::wheel_rotations(vertical, rotation_units))
|
||||
Self(
|
||||
<<$api as $crate::RemoteDesktopApi>::DeviceEvent as $crate::DeviceEvent>::wheel_rotations(
|
||||
vertical,
|
||||
rotation_units,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = keyPressed)]
|
||||
pub fn key_pressed(scancode: u16) -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent>::key_pressed(
|
||||
scancode,
|
||||
))
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent as $crate::DeviceEvent>::key_pressed(scancode))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = keyReleased)]
|
||||
pub fn key_released(scancode: u16) -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent>::key_released(
|
||||
scancode,
|
||||
))
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent as $crate::DeviceEvent>::key_released(scancode))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = unicodePressed)]
|
||||
pub fn unicode_pressed(unicode: char) -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent>::unicode_pressed(unicode))
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent as $crate::DeviceEvent>::unicode_pressed(unicode))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = unicodeReleased)]
|
||||
pub fn unicode_released(unicode: char) -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::DeviceEvent>::unicode_released(unicode))
|
||||
Self(
|
||||
<<$api as $crate::RemoteDesktopApi>::DeviceEvent as $crate::DeviceEvent>::unicode_released(unicode),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,12 +369,12 @@ macro_rules! make_bridge {
|
|||
impl InputTransaction {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn create() -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::InputTransaction>::create())
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::InputTransaction as $crate::InputTransaction>::create())
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = addEvent)]
|
||||
pub fn add_event(&mut self, event: DeviceEvent) {
|
||||
self.0.add_event(event.0);
|
||||
$crate::InputTransaction::add_event(&mut self.0, event.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,26 +383,30 @@ macro_rules! make_bridge {
|
|||
impl ClipboardData {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn create() -> Self {
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::ClipboardData>::create())
|
||||
Self(<<$api as $crate::RemoteDesktopApi>::ClipboardData as $crate::ClipboardData>::create())
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = addText)]
|
||||
pub fn add_text(&mut self, mime_type: &str, text: &str) {
|
||||
self.0.add_text(mime_type, text);
|
||||
$crate::ClipboardData::add_text(&mut self.0, mime_type, text);
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = addBinary)]
|
||||
pub fn add_binary(&mut self, mime_type: &str, binary: &[u8]) {
|
||||
self.0.add_binary(mime_type, binary);
|
||||
$crate::ClipboardData::add_binary(&mut self.0, mime_type, binary);
|
||||
}
|
||||
|
||||
pub fn items(&self) -> Vec<ClipboardItem> {
|
||||
self.0.items().into_iter().cloned().map(ClipboardItem).collect()
|
||||
$crate::ClipboardData::items(&self.0)
|
||||
.into_iter()
|
||||
.cloned()
|
||||
.map(ClipboardItem)
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = isEmpty)]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
$crate::ClipboardData::is_empty(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,11 +415,11 @@ macro_rules! make_bridge {
|
|||
impl ClipboardItem {
|
||||
#[wasm_bindgen(js_name = mimeType)]
|
||||
pub fn mime_type(&self) -> String {
|
||||
self.0.mime_type().to_owned()
|
||||
$crate::ClipboardItem::mime_type(&self.0).to_owned()
|
||||
}
|
||||
|
||||
pub fn value(&self) -> $crate::internal::wasm_bindgen::JsValue {
|
||||
self.0.value().into()
|
||||
$crate::ClipboardItem::value(&self.0).into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -396,11 +427,11 @@ macro_rules! make_bridge {
|
|||
#[doc(hidden)]
|
||||
impl IronError {
|
||||
pub fn backtrace(&self) -> String {
|
||||
self.0.backtrace()
|
||||
$crate::IronError::backtrace(&self.0)
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> $crate::IronErrorKind {
|
||||
self.0.kind()
|
||||
$crate::IronError::kind(&self.0)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -11,34 +11,49 @@ pub trait SessionBuilder {
|
|||
type Error: IronError;
|
||||
|
||||
fn create() -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn username(&self, username: String) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn destination(&self, destination: String) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn server_domain(&self, server_domain: String) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn password(&self, password: String) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn proxy_address(&self, address: String) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn auth_token(&self, token: String) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn desktop_size(&self, desktop_size: DesktopSize) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn render_canvas(&self, canvas: HtmlCanvasElement) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn set_cursor_style_callback(&self, callback: js_sys::Function) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn set_cursor_style_callback_context(&self, context: JsValue) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn remote_clipboard_changed_callback(&self, callback: js_sys::Function) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn remote_received_format_list_callback(&self, callback: js_sys::Function) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn force_clipboard_update_callback(&self, callback: js_sys::Function) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn extension(&self, ext: Extension) -> Self;
|
||||
|
||||
#[expect(async_fn_in_trait)]
|
||||
async fn connect(&self) -> Result<Self::Session, Self::Error>;
|
||||
}
|
||||
|
@ -50,9 +65,13 @@ pub trait Session {
|
|||
type Error: IronError;
|
||||
|
||||
fn run(&self) -> impl core::future::Future<Output = Result<Self::SessionTerminationInfo, Self::Error>>;
|
||||
|
||||
fn desktop_size(&self) -> DesktopSize;
|
||||
|
||||
fn apply_inputs(&self, transaction: Self::InputTransaction) -> Result<(), Self::Error>;
|
||||
|
||||
fn release_all_inputs(&self) -> Result<(), Self::Error>;
|
||||
|
||||
fn synchronize_lock_keys(
|
||||
&self,
|
||||
scroll_lock: bool,
|
||||
|
@ -60,11 +79,14 @@ pub trait Session {
|
|||
caps_lock: bool,
|
||||
kana_lock: bool,
|
||||
) -> Result<(), Self::Error>;
|
||||
|
||||
fn shutdown(&self) -> Result<(), Self::Error>;
|
||||
|
||||
fn on_clipboard_paste(
|
||||
&self,
|
||||
content: Self::ClipboardTransaction,
|
||||
) -> impl core::future::Future<Output = Result<(), Self::Error>>;
|
||||
|
||||
fn resize(
|
||||
&self,
|
||||
width: u32,
|
||||
|
@ -73,7 +95,9 @@ pub trait Session {
|
|||
physical_width: Option<u32>,
|
||||
physical_height: Option<u32>,
|
||||
);
|
||||
|
||||
fn supports_unicode_keyboard_shortcuts(&self) -> bool;
|
||||
|
||||
fn extension_call(ext: Extension) -> Result<JsValue, Self::Error>;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue