Rust矩阵协议库ruma-common的使用,提供Matrix协议基础类型和功能的Rust实现
ruma-common
用于其他Ruma crate的通用类型。
功能模块定义如下:
api
模块
在api
功能下,包含用于定义各种Matrix API规范中每个端点请求和响应的核心类型。这些类型可以被所有Matrix API的客户端和服务器代码共享。
events
模块
在events
功能下,包含Matrix规范中可序列化的事件类型,这些类型可以被客户端和服务器代码共享。
完整示例代码
以下是使用ruma-common创建Matrix事件的基本示例:
use ruma_common::events::{AnyMessageEvent, EventType};
use ruma_common::serde::Raw;
use serde_json::{json, value::to_raw_value};
fn main() {
// 创建一个文本消息事件
let event_json = json!({
"type": "m.room.message",
"content": {
"msgtype": "m.text",
"body": "Hello world!"
},
"sender": "@user:example.com",
"origin_server_ts": 1234567890,
"event_id": "$event_id:example.com"
});
// 将JSON转换为原始事件
let raw_event = Raw::from_json(to_raw_value(&event_json).unwrap());
// 解析为AnyMessageEvent
match raw_event.deserialize::<AnyMessageEvent>() {
Ok(event) => {
println!("成功解析事件: {:?}", event.event_type());
if let EventType::RoomMessage = event.event_type() {
println!("消息内容: {:?}", event.content());
}
}
Err(e) => eprintln!("解析事件失败: {}", e),
}
}
要使用此代码,你需要将以下内容添加到你的Cargo.toml中:
[dependencies]
ruma-common = { version = "0.15.4", features = ["events"] }
serde_json = "1.0"
这个示例展示了如何:
- 创建一个简单的Matrix房间消息事件JSON
- 将其转换为Raw事件格式
- 尝试解析为AnyMessageEvent类型
- 检查事件类型并访问内容
请注意,要使用events模块功能,你需要在Cargo.toml中明确启用events
功能。
完整示例demo
以下是一个更完整的示例,展示了如何处理不同类型的Matrix事件:
use ruma_common::events::{
room::message::{MessageEventContent, TextMessageEventContent},
AnyMessageEvent, AnyRoomEvent, AnySyncMessageEvent, AnySyncRoomEvent, EventType,
};
use ruma_common::serde::Raw;
use serde_json::{json, value::to_raw_value};
fn main() {
// 示例1: 处理文本消息事件
handle_text_message();
// 示例2: 处理自定义事件类型
handle_custom_event();
}
fn handle_text_message() {
println!("--- 处理文本消息事件 ---");
// 创建文本消息事件JSON
let event_json = json!({
"type": "m.room.message",
"content": {
"msgtype": "m.text",
"body": "Hello from Ruma!"
},
"sender": "@user:example.com",
"origin_server_ts": 1234567890,
"event_id": "$event_id:example.com"
});
// 转换为Raw格式
let raw_event = Raw::from_json(to_raw_value(&event_json).unwrap());
// 解析为AnyMessageEvent
match raw_event.deserialize::<AnyMessageEvent>() {
Ok(event) => {
println!("事件类型: {:?}", event.event_type());
if let EventType::RoomMessage = event.event_type() {
if let Some(content) = event.as_original() {
println!("发送者: {}", content.sender);
println!("消息内容: {}", content.content.body());
}
}
}
Err(e) => eprintln!("解析失败: {}", e),
}
}
fn handle_custom_event() {
println!("\n--- 处理自定义事件 ---");
// 创建自定义事件JSON
let custom_event_json = json!({
"type": "org.example.custom",
"content": {
"custom_field": "Some value",
"number": 42
},
"sender": "@bot:example.com",
"origin_server_ts": 9876543210,
"event_id": "$custom_event:example.com"
});
// 转换为Raw格式
let raw_event = Raw::from_json(to_raw_value(&custom_event_json).unwrap());
// 尝试解析为AnyRoomEvent
match raw_event.deserialize::<AnyRoomEvent>() {
Ok(event) => {
println!("自定义事件类型: {}", event.event_type().as_str());
println!("事件ID: {}", event.event_id());
println!("发送者: {}", event.sender());
}
Err(e) => eprintln!("解析自定义事件失败: {}", e),
}
}
对应的Cargo.toml配置:
[dependencies]
ruma-common = { version = "0.15.4", features = ["events"] }
serde_json = "1.0"
这个完整示例展示了:
- 如何处理标准文本消息事件
- 如何访问事件的各种属性(发送者、内容等)
- 如何处理自定义事件类型
- 如何使用不同的解析方法(AnyMessageEvent和AnyRoomEvent)
1 回复
Rust矩阵协议库ruma-common使用指南
ruma-common是Rust实现的Matrix协议基础库,提供了Matrix协议的核心类型和功能实现。
主要功能
- 实现了Matrix协议的核心数据结构
- 提供序列化/反序列化支持
- 包含各种Matrix事件类型
- 支持房间状态、消息事件等核心协议元素
使用方法
添加依赖
首先在Cargo.toml中添加依赖:
[dependencies]
ruma-common = "0.9.0"
基本类型使用示例
use ruma_common::{
events::room::message::RoomMessageEventContent,
RoomId, UserId,
};
fn main() {
// 创建用户ID
let user_id = UserId::parse("@alice:example.com").unwrap();
// 创建房间ID
let room_id = RoomId::parse("!roomid:example.com").unwrap();
// 创建文本消息内容
let message_content = RoomMessageEventContent::text_plain("Hello, Matrix!");
println!("User: {}", user_id);
println!("Room: {}", room_id);
println!("Message: {}", message_content.body());
}
事件处理示例
use ruma_common::{
events::{AnyMessageEvent, AnyRoomEvent, AnySyncMessageEvent},
serde::Raw,
};
// 处理原始事件JSON
fn process_event(raw: &Raw<AnyRoomEvent>) {
match raw.deserialize() {
Ok(AnyRoomEvent::Message(AnyMessageEvent::RoomMessage(message))) => {
println!("收到消息: {}", message.content.body());
}
Ok(event) => {
println!("收到其他类型事件: {:?}", event.event_type());
}
Err(e) => {
eprintln!("解析事件失败: {}", e);
}
}
}
自定义事件示例
use ruma_common::{
events::{room::message::MessageEventContent, EventType},
serde::StringEnum,
};
#[derive(Debug, Clone, StringEnum)]
pub enum CustomEventType {
#[ruma_enum(rename = "com.example.custom")]
Custom,
#[ruma_enum(rename = "com.example.another")]
Another,
#[ruma_enum(catch_all)]
_Custom(String),
}
#[derive(Debug, Clone, MessageEventContent)]
#[ruma_event(type = "com.example.custom", kind = Message)]
pub struct CustomEventContent {
pub custom_field: String,
pub number: i32,
}
高级功能
自定义JSON处理
use ruma_common::{
events::AnyMessageEvent,
serde::{Raw, Base64},
};
fn handle_custom_json(json_data: &str) {
let raw: Raw<AnyMessageEvent> = Raw::from_json_string(json_data).unwrap();
// 可以直接访问原始JSON
println!("原始JSON: {}", raw.json().get());
// 或者反序列化为具体事件
if let Ok(event) = raw.deserialize() {
println!("反序列化后事件: {:?}", event);
}
}
使用标识符生成器
use ruma_common::{
IdParseError, RoomId,
api::request::try_from_http_request,
};
fn generate_room_id(homeserver: &str) -> Result<RoomId, IdParseError> {
RoomId::parse(&format!("!{}:{}", random_string(), homeserver))
}
完整示例demo
下面是一个完整的ruma-common使用示例,展示了如何创建用户、房间、发送消息以及处理事件:
use ruma_common::{
events::{
room::message::{MessageType, RoomMessageEventContent},
AnyMessageEvent, AnyRoomEvent, AnySyncMessageEvent,
},
serde::Raw,
RoomId, UserId,
};
fn main() {
// 1. 创建基本类型
let user_id = UserId::parse("@alice:example.com").unwrap();
let room_id = RoomId::parse("!roomid:example.com").unwrap();
println!("用户: {}", user_id);
println!("房间: {}", room_id);
// 2. 创建并发送消息
let message_content = RoomMessageEventContent::text_plain("你好,Matrix世界!");
println!("消息内容: {}", message_content.body());
// 3. 模拟接收并处理事件
let event_json = r#"
{
"type": "m.room.message",
"content": {
"msgtype": "m.text",
"body": "Hello from Matrix!"
}
}"#;
process_raw_event(event_json);
// 4. 使用自定义事件
let custom_event = create_custom_event();
println!("自定义事件内容: {:?}", custom_event);
}
// 处理原始JSON事件
fn process_raw_event(json_data: &str) {
let raw: Raw<AnyRoomEvent> = Raw::from_json_string(json_data).unwrap();
match raw.deserialize() {
Ok(AnyRoomEvent::Message(AnyMessageEvent::RoomMessage(message))) => {
println!("处理消息事件: {}", message.content.body());
}
Ok(event) => {
println!("处理其他类型事件: {:?}", event.event_type());
}
Err(e) => {
eprintln!("事件解析错误: {}", e);
}
}
}
// 创建自定义事件
fn create_custom_event() -> CustomEventContent {
CustomEventContent {
custom_field: "自定义值".to_string(),
number: 42,
}
}
// 自定义事件类型定义
#[derive(Debug, Clone, ruma_common::serde::StringEnum)]
pub enum CustomEventType {
#[ruma_enum(rename = "com.example.custom")]
Custom,
#[ruma_enum(catch_all)]
_Custom(String),
}
// 自定义事件内容
#[derive(Debug, Clone, ruma_common::events::room::message::MessageEventContent)]
#[ruma_event(type = "com.example.custom", kind = ruma_common::events::MessageLikeEventType)]
pub struct CustomEventContent {
pub custom_field: String,
pub number: i32,
}
注意事项
- ruma-common主要提供基础类型,完整客户端功能需要结合ruma-client等库使用
- 大多数类型都实现了Serde的Serialize/Deserialize
- 错误处理很重要,许多操作返回Result类型
- 对于自定义事件,需要正确定义事件类型和内容结构
ruma-common是构建Matrix相关Rust应用的基础库,合理使用可以大大简化与Matrix协议交互的复杂度。