macro_rules! Stream {
() => { ... };
($l:lifetime) => { ... };
($channel:ident => $($token:tt)*) => { ... };
}Expand description
Type and expression macro for async WebSocket Message streams.
This macro can be used both where types are expected or where expressions are expected.
§Type Position
When used in a type position, the macro invoked as Stream['r] expands to:
MessageStream<'r, implStream<Item =Result<Message>>> + 'r>
The lifetime need not be specified as 'r. For instance, Stream['request]
is valid and expands as expected:
MessageStream<'request, implStream<Item =Result<Message>>> + 'request>
As a convenience, when the macro is invoked as Stream![], the lifetime
defaults to 'static. That is, Stream![] is equivalent to
Stream!['static].
§Expression Position
When invoked as an expression, the macro behaves similarly to Rocket’s
stream! macro. Specifically, it
supports yield and for await syntax. It is invoked as follows:
use rocket_ws as ws;
#[get("/")]
fn echo(ws: ws::WebSocket) -> ws::Stream![] {
ws::Stream! { ws =>
for await message in ws {
yield message?;
yield "foo".into();
yield vec![1, 2, 3, 4].into();
}
}
}It enjoins the following type requirements:
- The type of
wsmust beWebSocket.wscan be any ident. - The type of yielded expressions (
exprinyield expr) must beMessage. - The
Errtype of expressions short-circuited with?must beError.
The macro takes any series of statements and expands them into an expression
of type impl Stream<Item = Result<T>>, a stream that yields elements of
type Result<T>. It automatically converts yielded items of type T into
Ok(T). It supports any Rust statement syntax with the following
extensions:
-
?short-circuits stream termination onErrThe type of the error value must be
Error.
-
yield exprYields the result of evaluating
exprto the caller (the stream consumer) wrapped inOk.exprmust be of typeT.
-
for await x in stream { .. }awaits the next element instream, binds it tox, and executes the block with the binding.streammust implementStream<Item = T>; the type ofxisT.
§Examples
Borrow from the request. Send a single message and close:
use rocket_ws as ws;
#[get("/hello/<user>")]
fn ws_hello(ws: ws::WebSocket, user: &str) -> ws::Stream!['_] {
ws::Stream! { ws =>
yield user.into();
}
}Borrow from the request with explicit lifetime:
use rocket_ws as ws;
#[get("/hello/<user>")]
fn ws_hello<'r>(ws: ws::WebSocket, user: &'r str) -> ws::Stream!['r] {
ws::Stream! { ws =>
yield user.into();
}
}Emit several messages and short-circuit if the client sends a bad message:
use rocket_ws as ws;
#[get("/")]
fn echo(ws: ws::WebSocket) -> ws::Stream![] {
ws::Stream! { ws =>
for await message in ws {
for i in 0..5u8 {
yield i.to_string().into();
}
yield message?;
}
}
}