use asyncapi_rust::{AsyncApi, ToAsyncApiMessage, schemars::JsonSchema};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, JsonSchema, ToAsyncApiMessage)]
#[serde(tag = "type")]
pub enum ChatMessage {
#[serde(rename = "user.join")]
#[asyncapi(
summary = "User joins",
description = "Sent when a user enters a chat room"
)]
UserJoin { username: String, room: String },
#[serde(rename = "chat.message")]
#[asyncapi(
summary = "Chat message",
description = "A message from a user in a room"
)]
ChatMessage {
username: String,
room: String,
message: String,
},
#[serde(rename = "user.leave")]
#[asyncapi(summary = "User leaves", description = "Sent when a user exits a room")]
UserLeave { username: String, room: String },
}
#[derive(Serialize, Deserialize, JsonSchema, ToAsyncApiMessage)]
#[serde(tag = "type")]
pub enum SystemMessage {
#[serde(rename = "system.status")]
#[asyncapi(summary = "System status", description = "Server status update")]
Status { status: String, timestamp: u64 },
#[serde(rename = "system.error")]
#[asyncapi(summary = "System error", description = "Error occurred on the server")]
Error { code: String, message: String },
}
#[allow(clippy::duplicated_attributes)]
#[derive(AsyncApi)]
#[asyncapi(
title = "Chat API with Message Integration",
version = "1.0.0",
description = "Real-time chat API demonstrating automatic message integration"
)]
#[asyncapi_server(
name = "production",
host = "chat.example.com",
protocol = "wss",
description = "Production WebSocket server"
)]
#[asyncapi_channel(name = "chat", address = "/ws/chat")]
#[asyncapi_operation(name = "sendMessage", action = "send", channel = "chat")]
#[asyncapi_operation(name = "receiveMessage", action = "receive", channel = "chat")]
#[asyncapi_messages(ChatMessage, SystemMessage)]
struct ChatApi;
fn main() {
println!("=== Message Integration Example ===\n");
let spec = ChatApi::asyncapi_spec();
println!("API: {} v{}", spec.info.title, spec.info.version);
if let Some(desc) = &spec.info.description {
println!("Description: {}", desc);
}
println!();
if let Some(servers) = &spec.servers {
println!("Servers:");
for (name, server) in servers {
println!(" - {} ({}://{})", name, server.protocol, server.host);
}
println!();
}
if let Some(channels) = &spec.channels {
println!("Channels:");
for (name, channel) in channels {
if let Some(address) = &channel.address {
println!(" - {}: {}", name, address);
}
}
println!();
}
if let Some(operations) = &spec.operations {
println!("Operations:");
for (name, operation) in operations {
let action = match operation.action {
asyncapi_rust::OperationAction::Send => "send",
asyncapi_rust::OperationAction::Receive => "receive",
};
println!(
" - {}: {} to {}",
name, action, operation.channel.reference
);
}
println!();
}
if let Some(components) = &spec.components {
if let Some(messages) = &components.messages {
println!("Messages (automatically included from message types):");
for (name, message) in messages {
println!(" - {}", name);
if let Some(summary) = &message.summary {
println!(" Summary: {}", summary);
}
if let Some(desc) = &message.description {
println!(" Description: {}", desc);
}
}
println!();
}
}
println!("=== Complete AsyncAPI Specification (JSON) ===\n");
let json = serde_json::to_string_pretty(&spec).expect("Failed to serialize spec");
println!("{}", json);
}