define!() { /* proc-macro */ }api only.Expand description
Define API types.
Defining an endpoint causes a type to be generated which is a marker type
for the endpoint, which binds together the request and response types.
Defining a broadcast simply associated a broadcast with a marker type.
The marker type is used with the various types used when interacting with an API endpoint or broadcast, such as:
These are in turn extended with the relevant API using them:
yew021for yew0.21.x.
§Macro usage
The macro defines a set of endpoints and broadcasts, each of which is
represented by an uninhabitable type-level marker declared through a type
declaration.
On top of the API types, this macro also generates a debug_id function
with the following signature:
use musli_web::api::MessageId;
fn debug_id(id: MessageId) -> impl core::fmt::Debug {
}This method can be used to debug a message id, unknown message ids will be
identified with an Unknown(<number>) debug printing.
Each type-level marker will implement either api::Endpoint or
api::Broadcast. And they will have an associated constant named ID
which matches the kind that are assocaited with them.
These roughly follow the structure of:
pub type <name>;
impl Endpoint for <name> {
<definition>
}
impl Broadcast for <name> {
<definition>
}Implementing an Endpoint can define requests and responses. The first
response defined is required and is the default response that certain APIs
will expected the endpoint to return. Any number of requests can be
specified, this is allows for different “sender types” to be defined, but
their over the wire format has to be the same.
Types specified as request types have to implement musli::Encode and
types sets as response types must implemente musli::Decode.
(#[musli(..)])?
pub type Hello;
impl Endpoint for Hello (where <bounds>)? {
impl<'de> Request for HelloRequest<'de> (where <bounds>)?;
type Response<'de> = HelloResponse<'de> (where <bounds>)?;
}Implementing a Broadcast can define events, which are messages sent from
the server to the client. At least one event type is required, which will be
used as the default. Any number of events can be specified which allows for
different “sender types” to be defined, but their over the wire format has
to be the same.
(#[musli(..)])?
pub type Tick;
impl Broadcast for Tick (where <bounds>)? {
impl Event (<'lt>)? for OwnedTickEvent (where <bounds>)?;
}§Attributes
#[musli(kind = "...")]- Explicitly sets the kind of an endpoint or broadcast. Without it a string variant of the name of it will be used.
#[musli(kind = "tock")]
pub type Tick;
impl Broadcast for Tick {
impl Event for OwnedTickEvent;
impl<'de> Event for TickEvent<'de>;
}§Examples
use musli::{Decode, Encode};
use musli_web::api;
#[derive(Encode, Decode)]
pub struct HelloRequest<'de> {
pub message: &'de str,
}
#[derive(Encode, Decode)]
pub struct HelloResponse<'de> {
pub message: &'de str,
}
#[derive(Encode, Decode)]
pub struct TickEvent<'de> {
pub message: &'de str,
pub tick: u32,
}
#[derive(Encode, Decode)]
pub struct OwnedTickEvent {
pub message: String,
pub tick: u32,
}
api::define! {
pub type Hello;
impl Endpoint for Hello {
impl<'de> Request for HelloRequest<'de>;
type Response<'de> = HelloResponse<'de>;
}
#[musli(id = 100)]
pub type Tick;
impl Broadcast for Tick {
impl Event for OwnedTickEvent;
impl<'de> Event for TickEvent<'de>;
}
}
assert_eq!(format!("{:?}", debug_id(Hello::ID)), "Hello");
assert_eq!(format!("{:?}", debug_id(Tick::ID)), "Tick");