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"

这个示例展示了如何:

  1. 创建一个简单的Matrix房间消息事件JSON
  2. 将其转换为Raw事件格式
  3. 尝试解析为AnyMessageEvent类型
  4. 检查事件类型并访问内容

请注意,要使用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"

这个完整示例展示了:

  1. 如何处理标准文本消息事件
  2. 如何访问事件的各种属性(发送者、内容等)
  3. 如何处理自定义事件类型
  4. 如何使用不同的解析方法(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,
}

注意事项

  1. ruma-common主要提供基础类型,完整客户端功能需要结合ruma-client等库使用
  2. 大多数类型都实现了Serde的Serialize/Deserialize
  3. 错误处理很重要,许多操作返回Result类型
  4. 对于自定义事件,需要正确定义事件类型和内容结构

ruma-common是构建Matrix相关Rust应用的基础库,合理使用可以大大简化与Matrix协议交互的复杂度。

回到顶部