From afef9103a3d338f15f26b82d7a050dffbf0828eb Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 24 May 2022 11:54:41 +0200 Subject: [PATCH] feat(crypto-js): Continue to port the API to NodeJS. --- crates/matrix-sdk-crypto-js/Cargo.toml | 2 +- crates/matrix-sdk-crypto-js/src/errors.rs | 7 + crates/matrix-sdk-crypto-js/src/events.rs | 7 +- .../matrix-sdk-crypto-js/src/identifiers.rs | 171 +++++++++++++++--- crates/matrix-sdk-crypto-js/src/prelude.rs | 8 + 5 files changed, 164 insertions(+), 31 deletions(-) create mode 100644 crates/matrix-sdk-crypto-js/src/prelude.rs diff --git a/crates/matrix-sdk-crypto-js/Cargo.toml b/crates/matrix-sdk-crypto-js/Cargo.toml index 6080b04ca..2b4f35bae 100644 --- a/crates/matrix-sdk-crypto-js/Cargo.toml +++ b/crates/matrix-sdk-crypto-js/Cargo.toml @@ -34,7 +34,7 @@ matrix-sdk-crypto = { version = "0.5.0", path = "../matrix-sdk-crypto" } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] ruma = { version = "0.6.2", features = ["client-api-c", "rand", "unstable-msc2676", "unstable-msc2677"] } vodozemac = "0.2.0" -napi = { version = "2.4.3", default-features = false, features = ["napi4"], optional = true } +napi = { git = "https://github.com/Hywan/napi-rs", branch = "feat-tonapivalue-u16", default-features = false, features = ["napi4"], optional = true } napi-derive = { version = "2.4.1", optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/crates/matrix-sdk-crypto-js/src/errors.rs b/crates/matrix-sdk-crypto-js/src/errors.rs index cec0d369a..413ef54a9 100644 --- a/crates/matrix-sdk-crypto-js/src/errors.rs +++ b/crates/matrix-sdk-crypto-js/src/errors.rs @@ -14,3 +14,10 @@ where Self(napi::Error::from_reason(error.to_string())) } } + +#[cfg(feature = "nodejs")] +impl Into for Error { + fn into(self) -> napi::Error { + self.0 + } +} diff --git a/crates/matrix-sdk-crypto-js/src/events.rs b/crates/matrix-sdk-crypto-js/src/events.rs index 98d06afe8..a79dd8f6e 100644 --- a/crates/matrix-sdk-crypto-js/src/events.rs +++ b/crates/matrix-sdk-crypto-js/src/events.rs @@ -1,10 +1,11 @@ //! Types related to events. -use wasm_bindgen::prelude::*; +use crate::prelude::*; /// Who can see a room's history. -#[derive(Debug, Clone)] -#[wasm_bindgen] +#[cfg_attr(feature = "js", wasm_bindgen)] +#[cfg_attr(feature = "nodejs", napi)] +#[derive(Debug)] pub enum HistoryVisibility { /// Previous events are accessible to newly joined members from /// the point they were invited onwards. diff --git a/crates/matrix-sdk-crypto-js/src/identifiers.rs b/crates/matrix-sdk-crypto-js/src/identifiers.rs index 7623b54a7..5b1d21675 100644 --- a/crates/matrix-sdk-crypto-js/src/identifiers.rs +++ b/crates/matrix-sdk-crypto-js/src/identifiers.rs @@ -1,22 +1,22 @@ //! Types for [Matrix](https://matrix.org/) identifiers for devices, //! events, keys, rooms, servers, users and URIs. -use wasm_bindgen::prelude::*; +use crate::prelude::*; /// A Matrix [user ID]. /// /// [user ID]: https://spec.matrix.org/v1.2/appendices/#user-identifiers -#[wasm_bindgen] -#[derive(Debug, Clone)] +#[cfg_attr(feature = "js", wasm_bindgen)] +#[cfg_attr(feature = "nodejs", napi)] pub struct UserId { pub(crate) inner: ruma::OwnedUserId, } -#[wasm_bindgen] +#[cfg_attr(feature = "js", wasm_bindgen)] impl UserId { /// Parse/validate and create a new `UserId`. - #[wasm_bindgen(constructor)] - pub fn new(id: &str) -> Result { + #[cfg_attr(feature = "js", wasm_bindgen(constructor))] + pub fn new(id: &str) -> Result { Ok(Self { inner: ruma::UserId::parse(id)? }) } @@ -26,7 +26,7 @@ impl UserId { } /// Returns the server name of the user ID. - #[wasm_bindgen(js_name = "serverName")] + #[cfg_attr(feature = "js", wasm_bindgen(js_name = "serverName"))] pub fn server_name(&self) -> ServerName { ServerName { inner: self.inner.server_name().to_owned() } } @@ -36,57 +36,113 @@ impl UserId { /// A historical user ID is one that doesn't conform to the latest /// specification of the user ID grammar but is still accepted /// because it was previously allowed. - #[wasm_bindgen(getter, js_name = "isHistorical")] + #[cfg_attr(feature = "js", wasm_bindgen(getter, js_name = "isHistorical"))] pub fn is_historical(&self) -> bool { self.inner.is_historical() } /// Return the user ID as a string. - #[wasm_bindgen(js_name = "toString")] + #[cfg_attr(feature = "js", wasm_bindgen(js_name = "toString"))] pub fn to_string(&self) -> String { self.inner.as_str().to_owned() } } +#[cfg(feature = "nodejs")] +#[napi] +impl UserId { + /// Parse/validate and create a new `UserId`. + #[napi(constructor)] + pub fn new_(id: String) -> Result { + Self::new(id.as_ref()).map_err(Into::::into) + } + + /// Returns the user's localpart. + #[napi(js_name = "localpart")] + pub fn localpart_(&self) -> String { + self.localpart() + } + + /// Returns the server name of the user ID. + #[napi(js_name = "serverName")] + pub fn server_name_(&self) -> ServerName { + self.server_name() + } + + /// Whether this user ID is a historical one. + /// + /// A historical user ID is one that doesn't conform to the latest + /// specification of the user ID grammar but is still accepted + /// because it was previously allowed. + #[napi(getter, js_name = "isHistorical")] + pub fn is_historical_(&self) -> bool { + self.is_historical() + } + + /// Return the user ID as a string. + #[napi(js_name = "toString")] + pub fn to_string_(&self) -> String { + self.to_string() + } +} + /// A Matrix key ID. /// /// Device identifiers in Matrix are completely opaque character /// sequences. This type is provided simply for its semantic value. -#[wasm_bindgen] +#[cfg_attr(feature = "js", wasm_bindgen)] +#[cfg_attr(feature = "nodejs", napi)] #[derive(Debug, Clone)] pub struct DeviceId { pub(crate) inner: ruma::OwnedDeviceId, } -#[wasm_bindgen] +#[cfg_attr(feature = "js", wasm_bindgen)] impl DeviceId { /// Create a new `DeviceId`. - #[wasm_bindgen(constructor)] + #[cfg_attr(feature = "js", wasm_bindgen(constructor))] pub fn new(id: &str) -> DeviceId { Self { inner: id.into() } } /// Return the device ID as a string. - #[wasm_bindgen(js_name = "toString")] + #[cfg_attr(feature = "js", wasm_bindgen(js_name = "toString"))] pub fn to_string(&self) -> String { self.inner.as_str().to_owned() } } +#[cfg(feature = "nodejs")] +#[napi] +impl DeviceId { + /// Create a new `DeviceId`. + #[napi(constructor)] + pub fn new_(id: String) -> DeviceId { + Self::new(id.as_ref()) + } + + /// Return the device ID as a string. + #[napi(js_name = "toString")] + pub fn to_string_(&self) -> String { + self.to_string() + } +} + /// A Matrix [room ID]. /// /// [room ID]: https://spec.matrix.org/v1.2/appendices/#room-ids-and-event-ids -#[wasm_bindgen] +#[cfg_attr(feature = "js", wasm_bindgen)] +#[cfg_attr(feature = "nodejs", napi)] #[derive(Debug, Clone)] pub struct RoomId { pub(crate) inner: ruma::OwnedRoomId, } -#[wasm_bindgen] +#[cfg_attr(feature = "js", wasm_bindgen)] impl RoomId { - /// Parse/validate and create a new `UserId`. - #[wasm_bindgen(constructor)] - pub fn new(id: &str) -> Result { + /// Parse/validate and create a new `RoomId`. + #[cfg_attr(feature = "js", wasm_bindgen(constructor))] + pub fn new(id: &str) -> Result { Ok(Self { inner: ruma::RoomId::parse(id)? }) } @@ -95,36 +151,65 @@ impl RoomId { self.inner.localpart().to_owned() } - /// Returns the server name of the user ID. - #[wasm_bindgen(js_name = "serverName")] + /// Returns the server name of the room ID. + #[cfg_attr(feature = "js", wasm_bindgen(js_name = "serverName"))] pub fn server_name(&self) -> ServerName { ServerName { inner: self.inner.server_name().to_owned() } } - /// Return the device ID as a string. - #[wasm_bindgen(js_name = "toString")] + /// Return the room ID as a string. + #[cfg_attr(feature = "js", wasm_bindgen(js_name = "toString"))] pub fn to_string(&self) -> String { self.inner.as_str().to_owned() } } +#[cfg(feature = "nodejs")] +#[napi] +impl RoomId { + /// Parse/validate and create a new `RoomId`. + #[napi(constructor)] + pub fn new_(id: String) -> Result { + Self::new(id.as_ref()).map_err(Into::::into) + } + + /// Returns the user's localpart. + #[napi(js_name = "localpart")] + pub fn localpart_(&self) -> String { + self.localpart() + } + + /// Returns the server name of the room ID. + #[napi(js_name = "serverName")] + pub fn server_name_(&self) -> ServerName { + self.server_name() + } + + /// Return the room ID as a string. + #[napi(js_name = "toString")] + pub fn to_string_(&self) -> String { + self.to_string() + } +} + /// A Matrix-spec compliant [server name]. /// /// It consists of a host and an optional port (separated by a colon if /// present). /// /// [server name]: https://spec.matrix.org/v1.2/appendices/#server-name -#[wasm_bindgen] +#[cfg_attr(feature = "js", wasm_bindgen)] +#[cfg_attr(feature = "nodejs", napi)] #[derive(Debug)] pub struct ServerName { inner: ruma::OwnedServerName, } -#[wasm_bindgen] +#[cfg_attr(feature = "js", wasm_bindgen)] impl ServerName { /// Parse/validate and create a new `ServerName`. - #[wasm_bindgen(constructor)] - pub fn new(name: &str) -> Result { + #[cfg_attr(feature = "js", wasm_bindgen(constructor))] + pub fn new(name: &str) -> Result { Ok(Self { inner: ruma::ServerName::parse(name)? }) } @@ -143,8 +228,40 @@ impl ServerName { /// Returns true if and only if the server name is an IPv4 or IPv6 /// address. - #[wasm_bindgen(js_name = "isIpLiteral")] + #[cfg_attr(feature = "js", wasm_bindgen(js_name = "isIpLiteral"))] pub fn is_ip_literal(&self) -> bool { self.inner.is_ip_literal() } } + +#[cfg(feature = "nodejs")] +#[napi] +impl ServerName { + /// Parse/validate and create a new `ServerName`. + #[napi(constructor)] + pub fn new_(name: String) -> Result { + Self::new(name.as_ref()).map_err(Into::::into) + } + + /// Returns the host of the server name. + /// + /// That is: Return the part of the server before `:` or the + /// full server name if there is no port. + #[napi(js_name = "host")] + pub fn host_(&self) -> String { + self.host() + } + + /// Returns the port of the server name if any. + #[napi(js_name = "port")] + pub fn port_(&self) -> Option { + self.port() + } + + /// Returns true if and only if the server name is an IPv4 or IPv6 + /// address. + #[napi(js_name = "isIpLiteral")] + pub fn is_ip_literal_(&self) -> bool { + self.is_ip_literal() + } +} diff --git a/crates/matrix-sdk-crypto-js/src/prelude.rs b/crates/matrix-sdk-crypto-js/src/prelude.rs new file mode 100644 index 000000000..baa28a63d --- /dev/null +++ b/crates/matrix-sdk-crypto-js/src/prelude.rs @@ -0,0 +1,8 @@ +#[cfg(feature = "nodejs")] +pub use napi::bindgen_prelude::ToNapiValue; +#[cfg(feature = "nodejs")] +pub use napi_derive::napi; +#[cfg(feature = "js")] +pub use wasm_bindgen::prelude::*; + +pub use crate::errors::Error;