Struct MatrixMockServer

Source
pub struct MatrixMockServer { /* private fields */ }
Available on crate feature testing and non-WebAssembly only.
Expand description

A wiremock MockServer along with useful methods to help mocking Matrix client-server API endpoints easily.

It implements mock endpoints, limiting the shared code as much as possible, so the mocks are still flexible to use as scoped/unscoped mounts, named, and so on.

It works like this:

  • start by saying which endpoint you’d like to mock, e.g. Self::mock_room_send(). This returns a specialized MockEndpoint data structure, with its own impl. For this example, it’s MockEndpoint<RoomSendEndpoint>.
  • configure the response on the endpoint-specific mock data structure. For instance, if you want the sending to result in a transient failure, call MockEndpoint::error500; if you want it to succeed and return the event $42, call MockEndpoint::ok(). It’s still possible to call MockEndpoint::respond_with(), as we do with wiremock MockBuilder, for maximum flexibility when the helpers aren’t sufficient.
  • once the endpoint’s response is configured, for any mock builder, you get a MatrixMock; this is a plain wiremock::Mock with the server curried, so one doesn’t have to pass it around when calling MatrixMock::mount() or MatrixMock::mount_as_scoped(). As such, it mostly defers its implementations to wiremock::Mock under the hood.

§Examples

use matrix_sdk::{ruma::{room_id, event_id}, test_utils::mocks::MatrixMockServer};
use serde_json::json;

// First create the mock server and client pair.
let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

// Let's say that our rooms are not encrypted.
mock_server.mock_room_state_encryption().plain().mount().await;

// Let us get a room where we will send an event.
let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

// Now we mock the endpoint so we can actually send the event.
let event_id = event_id!("$some_id");
let send_guard = mock_server
    .mock_room_send()
    .ok(event_id)
    .expect(1)
    .mount_as_scoped()
    .await;

// And we send it out.
let response = room.send_raw("m.room.message", json!({ "body": "Hello world" })).await?;

assert_eq!(
    event_id,
    response.event_id,
    "The event ID we mocked should match the one we received when we sent the event"
);

Implementations§

Source§

impl MatrixMockServer

Source

pub async fn new() -> Self

Create a new wiremock server specialized for Matrix usage.

Source

pub fn from_server(server: MockServer) -> Self

Creates a new MatrixMockServer from a wiremock server.

Source

pub fn client_builder(&self) -> MockClientBuilder

Creates a new MockClientBuilder configured to use this server, preconfigured with a session expected by the server endpoints.

Source

pub fn server(&self) -> &MockServer

Return the underlying wiremock server.

Source

pub async fn sync_room( &self, client: &Client, room_data: impl Into<AnyRoomBuilder>, ) -> Room

Overrides the sync/ endpoint with knowledge that the given invited/joined/knocked/left room exists, runs a sync and returns the given room.

§Examples
use matrix_sdk::{ruma::{room_id, event_id}, test_utils::mocks::MatrixMockServer};
use matrix_sdk_test::LeftRoomBuilder;

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

let left_room = mock_server
    .sync_room(&client, LeftRoomBuilder::new(room_id!("!room_id:localhost")))
    .await;
Source

pub async fn sync_joined_room(&self, client: &Client, room_id: &RoomId) -> Room

Overrides the sync/ endpoint with knowledge that the given room exists in the joined state, runs a sync and returns the given room.

§Examples
use matrix_sdk::{ruma::room_id, test_utils::mocks::MatrixMockServer};

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;
Source

pub async fn verify_and_reset(&self)

Verify that the previous mocks expected number of requests match reality, and then cancels all active mocks.

§Examples
use matrix_sdk::{ruma::{room_id, event_id}, test_utils::mocks::MatrixMockServer};
use serde_json::json;

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server.mock_room_state_encryption().plain().mount().await;
let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;
mock_server.mock_room_send().ok(event_id!("$some_id")).mount().await;

// This will succeed.
let response = room.send_raw("m.room.message", json!({ "body": "Hello world" })).await?;

// Now we reset the mocks.
mock_server.verify_and_reset().await;

// And we can't send anymore.
let response = room
    .send_raw("m.room.message", json!({ "body": "Hello world" }))
    .await
    .expect_err("We removed the mock so sending should now fail");
Source§

impl MatrixMockServer

Source

pub fn mock_sync(&self) -> MockEndpoint<'_, SyncEndpoint>

Mocks a sync endpoint.

§Examples
use matrix_sdk::{ruma::room_id, test_utils::mocks::MatrixMockServer};
use matrix_sdk_test::JoinedRoomBuilder;

// First create the mock server and client pair.
let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;
let room_id = room_id!("!room_id:localhost");

// Let's emulate what `MatrixMockServer::sync_joined_room()` does.
mock_server
    .mock_sync()
    .ok_and_run(&client, |builder| {
        builder.add_joined_room(JoinedRoomBuilder::new(room_id));
    })
    .await;

let room = client
    .get_room(room_id)
    .expect("The room should be available after we mocked the sync");
Source

pub fn mock_room_send(&self) -> MockEndpoint<'_, RoomSendEndpoint>

Creates a prebuilt mock for sending an event in a room.

Note: works with any room.

§Examples
use matrix_sdk::{ruma::{room_id, event_id}, test_utils::mocks::MatrixMockServer};
use serde_json::json;

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server.mock_room_state_encryption().plain().mount().await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

let event_id = event_id!("$some_id");
mock_server
    .mock_room_send()
    .ok(event_id)
    .expect(1)
    .mount()
    .await;

let response = room.send_raw("m.room.message", json!({ "body": "Hello world" })).await?;

assert_eq!(
    event_id,
    response.event_id,
    "The event ID we mocked should match the one we received when we sent the event"
);
Source

pub fn mock_room_send_state(&self) -> MockEndpoint<'_, RoomSendStateEndpoint>

Creates a prebuilt mock for sending a state event in a room.

Similar to: MatrixMockServer::mock_room_send

Note: works with any room. Note: works with any event type.

use matrix_sdk::{ruma::{room_id, event_id}, test_utils::mocks::MatrixMockServer};
use serde_json::json;

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server.mock_room_state_encryption().plain().mount().await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

let event_id = event_id!("$some_id");
mock_server
    .mock_room_send_state()
    .ok(event_id)
    .expect(1)
    .mount()
    .await;

let response_not_mocked = room.send_raw("m.room.create", json!({ "body": "Hello world" })).await;
// The `/send` endpoint should not be mocked by the server.
assert!(response_not_mocked.is_err());


let response = room.send_state_event_raw("m.room.message", "my_key", json!({ "body": "Hello world" })).await?;
// The `/state` endpoint should be mocked by the server.
assert_eq!(
    event_id,
    response.event_id,
    "The event ID we mocked should match the one we received when we sent the event"
);
Source

pub fn mock_room_state_encryption( &self, ) -> MockEndpoint<'_, EncryptionStateEndpoint>

Creates a prebuilt mock for asking whether a room is encrypted or not.

Note: Applies to all rooms.

§Examples
use matrix_sdk::{ruma::room_id, test_utils::mocks::MatrixMockServer};

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server.mock_room_state_encryption().encrypted().mount().await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

assert!(
    room.is_encrypted().await?,
    "The room should be marked as encrypted."
);
Source

pub fn mock_set_room_state_encryption( &self, ) -> MockEndpoint<'_, SetEncryptionStateEndpoint>

Creates a prebuilt mock for setting the room encryption state.

Note: Applies to all rooms.

§Examples
use matrix_sdk::{
    ruma::{event_id, room_id},
    test_utils::mocks::MatrixMockServer,
};

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server.mock_room_state_encryption().plain().mount().await;
mock_server
    .mock_set_room_state_encryption()
    .ok(event_id!("$id"))
    .mock_once()
    .mount()
    .await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

room.enable_encryption()
    .await
    .expect("We should be able to enable encryption in the room");
Source

pub fn mock_room_redact(&self) -> MockEndpoint<'_, RoomRedactEndpoint>

Creates a prebuilt mock for the room redact endpoint.

§Examples
use matrix_sdk::{
    ruma::{event_id, room_id},
    test_utils::mocks::MatrixMockServer,
};

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;
let event_id = event_id!("$id");

mock_server.mock_room_redact().ok(event_id).mock_once().mount().await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

room.redact(event_id, None, None)
    .await
    .expect("We should be able to redact events in the room");
Source

pub fn mock_room_event(&self) -> MockEndpoint<'_, RoomEventEndpoint>

Creates a prebuilt mock for retrieving an event with /room/…/event.

Source

pub fn mock_room_messages(&self) -> MockEndpoint<'_, RoomMessagesEndpoint>

Create a prebuild mock for paginating room message with the /messages endpoint.

Source

pub fn mock_upload(&self) -> MockEndpoint<'_, UploadEndpoint>

Create a prebuilt mock for uploading media.

Source

pub fn mock_room_directory_resolve_alias( &self, ) -> MockEndpoint<'_, ResolveRoomAliasEndpoint>

Create a prebuilt mock for resolving room aliases.

§Examples
use matrix_sdk::{
    ruma::{owned_room_id, room_alias_id},
    test_utils::mocks::MatrixMockServer,
};
let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server
    .mock_room_directory_resolve_alias()
    .ok("!a:b.c", Vec::new())
    .mock_once()
    .mount()
    .await;

let res = client
    .resolve_room_alias(room_alias_id!("#a:b.c"))
    .await
    .expect("We should be able to resolve the room alias");
assert_eq!(res.room_id, owned_room_id!("!a:b.c"));
Source

pub fn mock_room_directory_create_room_alias( &self, ) -> MockEndpoint<'_, CreateRoomAliasEndpoint>

Create a prebuilt mock for publishing room aliases in the room directory.

§Examples
use matrix_sdk::{
    ruma::{room_alias_id, room_id},
    test_utils::mocks::MatrixMockServer,
};

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server
    .mock_room_directory_create_room_alias()
    .ok()
    .mock_once()
    .mount()
    .await;

client
    .create_room_alias(room_alias_id!("#a:b.c"), room_id!("!a:b.c"))
    .await
    .expect("We should be able to create a room alias");
Source

pub fn mock_room_directory_remove_room_alias( &self, ) -> MockEndpoint<'_, RemoveRoomAliasEndpoint>

Create a prebuilt mock for removing room aliases from the room directory.

§Examples
use matrix_sdk::{
    ruma::room_alias_id, test_utils::mocks::MatrixMockServer,
};

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server
    .mock_room_directory_remove_room_alias()
    .ok()
    .mock_once()
    .mount()
    .await;

client
    .remove_room_alias(room_alias_id!("#a:b.c"))
    .await
    .expect("We should be able to remove the room alias");
Source

pub fn mock_public_rooms(&self) -> MockEndpoint<'_, PublicRoomsEndpoint>

Create a prebuilt mock for listing public rooms.

§Examples
tokio_test::block_on(async {
use js_int::uint;
use ruma::directory::PublicRoomsChunkInit;
use matrix_sdk::room_directory_search::RoomDirectorySearch;
use matrix_sdk::{
    ruma::{event_id, room_id},
    test_utils::mocks::MatrixMockServer,
};
let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;
let event_id = event_id!("$id");
let room_id = room_id!("!room_id:localhost");

let chunk = vec![PublicRoomsChunkInit {
    num_joined_members: uint!(0),
    room_id: room_id.to_owned(),
    world_readable: true,
    guest_can_join: true,
}.into()];

mock_server.mock_public_rooms().ok(chunk, None, None, Some(20)).mock_once().mount().await;
let mut room_directory_search = RoomDirectorySearch::new(client);

room_directory_search.search(Some("some-alias".to_owned()), 100, None)
    .await
    .expect("Room directory search failed");

let (results, _) = room_directory_search.results();
assert_eq!(results.len(), 1);
assert_eq!(results.get(0).unwrap().room_id, room_id.to_owned());
Source

pub fn mock_room_directory_set_room_visibility( &self, ) -> MockEndpoint<'_, SetRoomVisibilityEndpoint>

Create a prebuilt mock for setting a room’s visibility in the room directory.

§Examples
use matrix_sdk::{ruma::room_id, test_utils::mocks::MatrixMockServer};
use ruma::api::client::room::Visibility;

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server
    .mock_room_directory_set_room_visibility()
    .ok()
    .mock_once()
    .mount()
    .await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

room.privacy_settings()
    .update_room_visibility(Visibility::Private)
    .await
    .expect("We should be able to update the room's visibility");
Source

pub fn mock_room_directory_get_room_visibility( &self, ) -> MockEndpoint<'_, GetRoomVisibilityEndpoint>

Create a prebuilt mock for getting a room’s visibility in the room directory.

§Examples
use matrix_sdk::{ruma::room_id, test_utils::mocks::MatrixMockServer};
use ruma::api::client::room::Visibility;

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server
    .mock_room_directory_get_room_visibility()
    .ok(Visibility::Public)
    .mock_once()
    .mount()
    .await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

let visibility = room
    .privacy_settings()
    .get_room_visibility()
    .await
    .expect("We should be able to get the room's visibility");
assert_eq!(visibility, Visibility::Public);
Source

pub fn mock_room_keys_version( &self, ) -> MockEndpoint<'_, RoomKeysVersionEndpoint>

Create a prebuilt mock for fetching information about key storage backups.

§Examples
use matrix_sdk::test_utils::mocks::MatrixMockServer;

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server.mock_room_keys_version().exists().expect(1).mount().await;

let exists =
    client.encryption().backups().fetch_exists_on_server().await.unwrap();

assert!(exists);
Source

pub fn mock_add_room_keys_version( &self, ) -> MockEndpoint<'_, AddRoomKeysVersionEndpoint>

Create a prebuilt mock for adding key storage backups via POST

Source

pub fn mock_delete_room_keys_version( &self, ) -> MockEndpoint<'_, DeleteRoomKeysVersionEndpoint>

Create a prebuilt mock for adding key storage backups via POST

Source

pub fn mock_get_members(&self) -> MockEndpoint<'_, GetRoomMembersEndpoint>

Create a prebuilt mock for getting the room members in a room.

§Examples
use matrix_sdk::{
    ruma::{event_id, room_id},
    test_utils::mocks::MatrixMockServer,
};
use matrix_sdk_base::RoomMemberships;
use matrix_sdk_test::event_factory::EventFactory;
use ruma::{
    events::room::member::{MembershipState, RoomMemberEventContent},
    user_id,
};
let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;
let event_id = event_id!("$id");
let room_id = room_id!("!room_id:localhost");

let f = EventFactory::new().room(room_id);
let alice_user_id = user_id!("@alice:b.c");
let alice_knock_event = f
    .event(RoomMemberEventContent::new(MembershipState::Knock))
    .event_id(event_id)
    .sender(alice_user_id)
    .state_key(alice_user_id)
    .into_raw_timeline()
    .cast();

mock_server
    .mock_get_members()
    .ok(vec![alice_knock_event])
    .mock_once()
    .mount()
    .await;
let room = mock_server.sync_joined_room(&client, room_id).await;

let members = room.members(RoomMemberships::all()).await.unwrap();
assert_eq!(members.len(), 1);
Source

pub fn mock_invite_user_by_id(&self) -> MockEndpoint<'_, InviteUserByIdEndpoint>

Creates a prebuilt mock for inviting a user to a room by its id.

§Examples
tokio_test::block_on(async {
use matrix_sdk::{
    ruma::room_id,
    test_utils::mocks::MatrixMockServer,
};

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server.mock_invite_user_by_id().ok().mock_once().mount().await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

room.invite_user_by_id(user_id!("@alice:localhost")).await.unwrap();
Source

pub fn mock_kick_user(&self) -> MockEndpoint<'_, KickUserEndpoint>

Creates a prebuilt mock for kicking a user from a room.

§Examples
tokio_test::block_on(async {
use matrix_sdk::{
    ruma::room_id,
    test_utils::mocks::MatrixMockServer,
};

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server.mock_kick_user().ok().mock_once().mount().await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

room.kick_user(user_id!("@alice:localhost"), None).await.unwrap();
Source

pub fn mock_ban_user(&self) -> MockEndpoint<'_, BanUserEndpoint>

Creates a prebuilt mock for banning a user from a room.

§Examples
tokio_test::block_on(async {
use matrix_sdk::{
    ruma::room_id,
    test_utils::mocks::MatrixMockServer,
};

let mock_server = MatrixMockServer::new().await;
let client = mock_server.client_builder().build().await;

mock_server.mock_ban_user().ok().mock_once().mount().await;

let room = mock_server
    .sync_joined_room(&client, room_id!("!room_id:localhost"))
    .await;

room.ban_user(user_id!("@alice:localhost"), None).await.unwrap();
Source

pub fn mock_versions(&self) -> MockEndpoint<'_, VersionsEndpoint>

Creates a prebuilt mock for the /_matrix/client/versions endpoint.

Source

pub fn mock_room_summary(&self) -> MockEndpoint<'_, RoomSummaryEndpoint>

Creates a prebuilt mock for the room summary endpoint MSC3266.

Source

pub fn mock_set_room_pinned_events( &self, ) -> MockEndpoint<'_, SetRoomPinnedEventsEndpoint>

Creates a prebuilt mock for the endpoint used to set a room’s pinned events.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CompatExt for T

§

fn compat(self) -> Compat<T>

Applies the [Compat] adapter by value. Read more
§

fn compat_ref(&self) -> Compat<&T>

Applies the [Compat] adapter by shared reference. Read more
§

fn compat_mut(&mut self) -> Compat<&mut T>

Applies the [Compat] adapter by mutable reference. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T, UT> HandleAlloc<UT> for T
where T: Send + Sync,

Source§

fn new_handle(value: Arc<T>) -> Handle

Create a new handle for an Arc value Read more
Source§

fn clone_handle(handle: Handle) -> Handle

Clone a handle Read more
Source§

fn consume_handle(handle: Handle) -> Arc<T>

Consume a handle, getting back the initial Arc<>
Source§

fn get_arc(handle: Handle) -> Arc<Self>

Get a clone of the Arc<> using a “borrowed” handle. Read more
Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
Source§

impl<T> Any for T
where T: Any,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T

Source§

impl<T> SendOutsideWasm for T
where T: Send,

Source§

impl<T> SyncOutsideWasm for T
where T: Sync,