use asyncapi_rust::{AsyncApi, ToAsyncApiMessage, schemars::JsonSchema};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, ToAsyncApiMessage)]
#[serde(tag = "type")]
pub enum ChatMessage {
#[serde(rename = "join")]
#[asyncapi(
summary = "User joins a room",
description = "Sent when a user enters a chat room"
)]
Join {
username: String,
room: String,
},
#[serde(rename = "message")]
#[asyncapi(
summary = "Send a chat message",
description = "Broadcast a message to all users in a room"
)]
Message {
username: String,
room: String,
text: String,
},
#[serde(rename = "leave")]
#[asyncapi(
summary = "User leaves a room",
description = "Sent when a user exits a chat room"
)]
Leave {
username: String,
room: String,
},
}
#[allow(clippy::duplicated_attributes)] #[derive(AsyncApi)]
#[asyncapi(
title = "Chat WebSocket API",
version = "1.0.0",
description = "Real-time chat application using actix-ws"
)]
#[asyncapi_server(name = "development", host = "localhost:8080", protocol = "ws")]
#[asyncapi_channel(name = "chat", address = "/ws")]
#[asyncapi_operation(name = "sendMessage", action = "send", channel = "chat")]
#[asyncapi_operation(name = "receiveMessage", action = "receive", channel = "chat")]
struct ChatApi;
fn main() {
println!("🚀 actix-web + AsyncAPI Integration Example\n");
let spec = ChatApi::asyncapi_spec();
println!("📋 API Specification:");
println!(" Title: {}", spec.info.title);
println!(" Version: {}", spec.info.version);
println!();
println!("📨 Message Types:");
for name in ChatMessage::asyncapi_message_names() {
println!(" • {}", name);
}
println!();
let messages = ChatMessage::asyncapi_messages();
println!("✅ Generated {} message schemas\n", messages.len());
let spec_json = serde_json::to_string_pretty(&spec).unwrap();
println!("📄 AsyncAPI Specification:\n{}\n", spec_json);
println!("💡 Integration Points:");
println!(" • ChatMessage enum used in WebSocket handlers");
println!(" • serde for JSON serialization/deserialization");
println!(" • AsyncAPI spec generated from the same code");
println!(" • Type safety enforced at compile time");
println!();
println!("🔗 Next Steps:");
println!(" 1. Add actix-web and actix-ws dependencies");
println!(" 2. Implement WebSocket handler using ChatMessage");
println!(" 3. Use serde_json to parse incoming messages");
println!(" 4. Export spec to docs/asyncapi.json for documentation");
println!();
println!("📚 Example Handler Pattern:");
println!(
r#"
async fn websocket_handler(
req: HttpRequest,
stream: web::Payload,
) -> Result<HttpResponse, Error> {{
let (response, session, mut msg_stream) = actix_ws::handle(&req, stream)?;
actix_web::rt::spawn(async move {{
while let Some(Ok(msg)) = msg_stream.next().await {{
if let actix_ws::Message::Text(text) = msg {{
// Parse incoming message
if let Ok(chat_msg) = serde_json::from_str::<ChatMessage>(&text) {{
match chat_msg {{
ChatMessage::Join {{ username, room }} => {{
// Handle join
}}
ChatMessage::Message {{ username, room, text }} => {{
// Handle message
}}
ChatMessage::Leave {{ username, room }} => {{
// Handle leave
}}
}}
}}
}}
}}
}});
Ok(response)
}}
"#
);
}