mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-09-10 22:22:48 +02:00
Upload files to "src/core"
This commit is contained in:
parent
f84966f5a2
commit
baa720b769
4 changed files with 1599 additions and 0 deletions
408
src/core/docs_api_guide.rs
Normal file
408
src/core/docs_api_guide.rs
Normal file
|
@ -0,0 +1,408 @@
|
||||||
|
//! API Guide for Continuwuity Enhanced Types
|
||||||
|
//!
|
||||||
|
//! This module provides a comprehensive guide for using our enhanced types
|
||||||
|
//! and error handling in Continuwuity applications.
|
||||||
|
|
||||||
|
use crate::types::*;
|
||||||
|
use crate::error::*;
|
||||||
|
|
||||||
|
/// API Guide: Enhanced Error Handling
|
||||||
|
///
|
||||||
|
/// Our enhanced error system provides better user experience and debugging capabilities.
|
||||||
|
///
|
||||||
|
/// # Key Features
|
||||||
|
///
|
||||||
|
/// - **User-friendly messages**: Clear, actionable error messages for users
|
||||||
|
/// - **Sanitized logging**: Safe error messages for logs without sensitive data
|
||||||
|
/// - **Matrix compliance**: Proper Matrix error codes and HTTP status codes
|
||||||
|
/// - **Contextual information**: Rich error context for better debugging
|
||||||
|
///
|
||||||
|
/// # Usage Examples
|
||||||
|
///
|
||||||
|
/// ## Creating Errors
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::error::*;
|
||||||
|
///
|
||||||
|
/// // Authentication errors
|
||||||
|
/// let auth_error = EnhancedError::auth_failed("Invalid token");
|
||||||
|
///
|
||||||
|
/// // Room errors
|
||||||
|
/// let room_error = EnhancedError::room_not_found("!room123:example.com");
|
||||||
|
///
|
||||||
|
/// // User errors
|
||||||
|
/// let user_error = EnhancedError::user_not_found("@user:example.com");
|
||||||
|
///
|
||||||
|
/// // Permission errors
|
||||||
|
/// let perm_error = EnhancedError::insufficient_permissions("Admin role required");
|
||||||
|
///
|
||||||
|
/// // Federation errors
|
||||||
|
/// let fed_error = EnhancedError::federation_error("matrix.org", "Connection timeout");
|
||||||
|
///
|
||||||
|
/// // Configuration errors
|
||||||
|
/// let config_error = EnhancedError::config_error("database_url", "Invalid format");
|
||||||
|
///
|
||||||
|
/// // Database errors
|
||||||
|
/// let db_error = EnhancedError::database_error("user_lookup", "Connection lost");
|
||||||
|
///
|
||||||
|
/// // Network errors
|
||||||
|
/// let net_error = EnhancedError::network_error("federation", "DNS resolution failed");
|
||||||
|
///
|
||||||
|
/// // Validation errors
|
||||||
|
/// let val_error = EnhancedError::validation_error("room_name", "Too long");
|
||||||
|
///
|
||||||
|
/// // Rate limit errors
|
||||||
|
/// let rate_error = EnhancedError::rate_limit_exceeded("room_creation", 60);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Using Error Information
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::error::*;
|
||||||
|
///
|
||||||
|
/// let error = EnhancedError::room_not_found("!room123:example.com");
|
||||||
|
///
|
||||||
|
/// // Get user-friendly message
|
||||||
|
/// let user_msg = error.user_message();
|
||||||
|
/// // "The room '!room123:example.com' could not be found. It may have been deleted or you may not have access."
|
||||||
|
///
|
||||||
|
/// // Get sanitized message for logging
|
||||||
|
/// let log_msg = error.sanitized_message();
|
||||||
|
/// // "Room not found: !room123:example.com"
|
||||||
|
///
|
||||||
|
/// // Get Matrix error code
|
||||||
|
/// let matrix_code = error.matrix_error_code();
|
||||||
|
/// // "M_NOT_FOUND"
|
||||||
|
///
|
||||||
|
/// // Get HTTP status code
|
||||||
|
/// let http_code = error.http_status_code();
|
||||||
|
/// // 404
|
||||||
|
/// ```
|
||||||
|
pub fn enhanced_error_guide() {
|
||||||
|
// This function demonstrates the enhanced error handling API
|
||||||
|
let _auth_error = EnhancedError::auth_failed("Invalid token");
|
||||||
|
let _room_error = EnhancedError::room_not_found("!room123:example.com");
|
||||||
|
let _user_error = EnhancedError::user_not_found("@user:example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// API Guide: Enhanced Room Types
|
||||||
|
///
|
||||||
|
/// Our enhanced room types provide better organization and functionality for room operations.
|
||||||
|
///
|
||||||
|
/// # Key Features
|
||||||
|
///
|
||||||
|
/// - **Rich room information**: Comprehensive room data with metadata
|
||||||
|
/// - **Permission checking**: Built-in methods for checking user permissions
|
||||||
|
/// - **Power level management**: Easy power level configuration and checking
|
||||||
|
/// - **State management**: Proper room state handling
|
||||||
|
///
|
||||||
|
/// # Usage Examples
|
||||||
|
///
|
||||||
|
/// ## Creating Room Information
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let room = EnhancedRoomInfo::new("!room123:example.com".to_string());
|
||||||
|
///
|
||||||
|
/// // Set room properties
|
||||||
|
/// let mut room = EnhancedRoomInfo::new("!room123:example.com".to_string());
|
||||||
|
/// room.name = Some("My Awesome Room".to_string());
|
||||||
|
/// room.topic = Some("A room for awesome discussions".to_string());
|
||||||
|
/// room.is_public = true;
|
||||||
|
/// room.join_rule = JoinRule::Public;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Checking Permissions
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let room = EnhancedRoomInfo::new("!room123:example.com".to_string());
|
||||||
|
///
|
||||||
|
/// // Check if user is admin
|
||||||
|
/// let is_admin = room.is_admin("@admin:example.com");
|
||||||
|
///
|
||||||
|
/// // Check if user can send messages
|
||||||
|
/// let can_send = room.can_send_message("@user:example.com");
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Power Level Management
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
/// use std::collections::HashMap;
|
||||||
|
///
|
||||||
|
/// let mut power_levels = PowerLevels::default();
|
||||||
|
/// power_levels.users.insert("@admin:example.com".to_string(), 100);
|
||||||
|
/// power_levels.users.insert("@moderator:example.com".to_string(), 50);
|
||||||
|
/// power_levels.events_default = 0;
|
||||||
|
/// power_levels.state_default = 50;
|
||||||
|
/// ```
|
||||||
|
pub fn enhanced_room_guide() {
|
||||||
|
// This function demonstrates the enhanced room types API
|
||||||
|
let room = EnhancedRoomInfo::new("!room123:example.com".to_string());
|
||||||
|
let _is_admin = room.is_admin("@admin:example.com");
|
||||||
|
let _can_send = room.can_send_message("@user:example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// API Guide: Enhanced User Types
|
||||||
|
///
|
||||||
|
/// Our enhanced user types provide better user information and management.
|
||||||
|
///
|
||||||
|
/// # Key Features
|
||||||
|
///
|
||||||
|
/// - **Rich user information**: Comprehensive user data with presence
|
||||||
|
/// - **Membership checking**: Built-in methods for checking user membership
|
||||||
|
/// - **Permission checking**: Easy permission level checking
|
||||||
|
/// - **Profile management**: Complete user profile information
|
||||||
|
///
|
||||||
|
/// # Usage Examples
|
||||||
|
///
|
||||||
|
/// ## Creating User Information
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let user = EnhancedUserInfo::new("@user:example.com".to_string());
|
||||||
|
///
|
||||||
|
/// // Set user properties
|
||||||
|
/// let mut user = EnhancedUserInfo::new("@user:example.com".to_string());
|
||||||
|
/// user.display_name = Some("Alice".to_string());
|
||||||
|
/// user.avatar_url = Some("mxc://example.com/avatar123".to_string());
|
||||||
|
/// user.is_online = true;
|
||||||
|
/// user.power_level = 50;
|
||||||
|
/// user.membership_state = MembershipState::Join;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Checking User Status
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let user = EnhancedUserInfo::new("@user:example.com".to_string());
|
||||||
|
///
|
||||||
|
/// // Check if user is a member
|
||||||
|
/// let is_member = user.is_member();
|
||||||
|
///
|
||||||
|
/// // Check if user is a moderator
|
||||||
|
/// let is_moderator = user.is_moderator();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## User Profiles
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let profile = EnhancedUserProfile {
|
||||||
|
/// user_id: "@alice:example.com".to_string(),
|
||||||
|
/// display_name: Some("Alice".to_string()),
|
||||||
|
/// avatar_url: Some("mxc://example.com/avatar123".to_string()),
|
||||||
|
/// is_online: true,
|
||||||
|
/// last_seen: Some(1640995200),
|
||||||
|
/// presence: PresenceState::Online,
|
||||||
|
/// status_msg: Some("Working on Matrix stuff".to_string()),
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
|
pub fn enhanced_user_guide() {
|
||||||
|
// This function demonstrates the enhanced user types API
|
||||||
|
let user = EnhancedUserInfo::new("@user:example.com".to_string());
|
||||||
|
let _is_member = user.is_member();
|
||||||
|
let _is_moderator = user.is_moderator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// API Guide: Enhanced Message Types
|
||||||
|
///
|
||||||
|
/// Our enhanced message types provide better message handling and processing.
|
||||||
|
///
|
||||||
|
/// # Key Features
|
||||||
|
///
|
||||||
|
/// - **Rich message content**: Comprehensive message data with metadata
|
||||||
|
/// - **Reply handling**: Built-in support for message replies
|
||||||
|
/// - **Thread support**: Easy thread message handling
|
||||||
|
/// - **Mention support**: Built-in mention handling
|
||||||
|
///
|
||||||
|
/// # Usage Examples
|
||||||
|
///
|
||||||
|
/// ## Creating Messages
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// // Create a simple text message
|
||||||
|
/// let message = EnhancedMessageContent::new_text("Hello, world!".to_string());
|
||||||
|
///
|
||||||
|
/// // Create a notice message
|
||||||
|
/// let notice = EnhancedMessageContent::new_notice("System message".to_string());
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Creating Replies
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let mut reply = EnhancedMessageContent::new_text("This is a reply".to_string());
|
||||||
|
/// reply.relates_to = Some(RelatesTo {
|
||||||
|
/// in_reply_to: Some(InReplyTo {
|
||||||
|
/// event_id: "$original_event_id".to_string(),
|
||||||
|
/// }),
|
||||||
|
/// rel_type: None,
|
||||||
|
/// event_id: None,
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// // Check if message is a reply
|
||||||
|
/// let is_reply = reply.is_reply();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Creating Thread Messages
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let mut thread_message = EnhancedMessageContent::new_text("Thread message".to_string());
|
||||||
|
/// thread_message.thread = Some(ThreadInfo {
|
||||||
|
/// event_id: "$thread_root_event_id".to_string(),
|
||||||
|
/// is_falling_back: None,
|
||||||
|
/// is_editing: None,
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// // Check if message is in a thread
|
||||||
|
/// let is_thread = thread_message.is_thread();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Adding Mentions
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let mut message = EnhancedMessageContent::new_text("Hello @alice:example.com!".to_string());
|
||||||
|
/// message.mentions = Some(Mentions {
|
||||||
|
/// user_ids: vec!["@alice:example.com".to_string()],
|
||||||
|
/// room: false,
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
|
pub fn enhanced_message_guide() {
|
||||||
|
// This function demonstrates the enhanced message types API
|
||||||
|
let message = EnhancedMessageContent::new_text("Hello, world!".to_string());
|
||||||
|
let _is_reply = message.is_reply();
|
||||||
|
let _is_thread = message.is_thread();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// API Guide: Room Creation and Management
|
||||||
|
///
|
||||||
|
/// Our enhanced types provide better room creation and management capabilities.
|
||||||
|
///
|
||||||
|
/// # Key Features
|
||||||
|
///
|
||||||
|
/// - **Structured room creation**: Well-defined room creation requests
|
||||||
|
/// - **Member management**: Easy room member handling
|
||||||
|
/// - **Room summaries**: Rich room information for listings
|
||||||
|
/// - **State management**: Proper room state handling
|
||||||
|
///
|
||||||
|
/// # Usage Examples
|
||||||
|
///
|
||||||
|
/// ## Creating Rooms
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let room_request = EnhancedRoomCreateRequest {
|
||||||
|
/// name: Some("My Awesome Room".to_string()),
|
||||||
|
/// topic: Some("A room for awesome discussions".to_string()),
|
||||||
|
/// preset: Some(RoomPreset::PublicChat),
|
||||||
|
/// room_version: Some("10".to_string()),
|
||||||
|
/// is_direct: Some(false),
|
||||||
|
/// invite: Some(vec!["@alice:example.com".to_string()]),
|
||||||
|
/// initial_state: None,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Managing Room Members
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let member = EnhancedRoomMember {
|
||||||
|
/// user_id: "@alice:example.com".to_string(),
|
||||||
|
/// display_name: Some("Alice".to_string()),
|
||||||
|
/// avatar_url: Some("mxc://example.com/avatar123".to_string()),
|
||||||
|
/// membership: MembershipState::Join,
|
||||||
|
/// power_level: 50,
|
||||||
|
/// is_direct: false,
|
||||||
|
/// third_party_invite: None,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Room Summaries
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let room_summary = EnhancedRoomSummary {
|
||||||
|
/// room_id: "!room123:example.com".to_string(),
|
||||||
|
/// name: Some("General Discussion".to_string()),
|
||||||
|
/// topic: Some("A place for general chat".to_string()),
|
||||||
|
/// avatar_url: Some("mxc://example.com/room_avatar".to_string()),
|
||||||
|
/// member_count: 42,
|
||||||
|
/// is_public: true,
|
||||||
|
/// last_activity: 1640995200,
|
||||||
|
/// unread_count: 5,
|
||||||
|
/// highlight_count: 2,
|
||||||
|
/// notification_count: 7,
|
||||||
|
/// };
|
||||||
|
/// ```
|
||||||
|
pub fn room_management_guide() {
|
||||||
|
// This function demonstrates the room management API
|
||||||
|
let _room_request = EnhancedRoomCreateRequest {
|
||||||
|
name: Some("Example Room".to_string()),
|
||||||
|
topic: Some("Example topic".to_string()),
|
||||||
|
preset: Some(RoomPreset::PublicChat),
|
||||||
|
room_version: Some("10".to_string()),
|
||||||
|
is_direct: Some(false),
|
||||||
|
invite: None,
|
||||||
|
initial_state: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let _room_summary = EnhancedRoomSummary {
|
||||||
|
room_id: "!room123:example.com".to_string(),
|
||||||
|
name: Some("General Discussion".to_string()),
|
||||||
|
topic: Some("A place for general chat".to_string()),
|
||||||
|
avatar_url: Some("mxc://example.com/room_avatar".to_string()),
|
||||||
|
member_count: 42,
|
||||||
|
is_public: true,
|
||||||
|
last_activity: 1640995200,
|
||||||
|
unread_count: 5,
|
||||||
|
highlight_count: 2,
|
||||||
|
notification_count: 7,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enhanced_error_guide() {
|
||||||
|
enhanced_error_guide();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enhanced_room_guide() {
|
||||||
|
enhanced_room_guide();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enhanced_user_guide() {
|
||||||
|
enhanced_user_guide();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enhanced_message_guide() {
|
||||||
|
enhanced_message_guide();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_room_management_guide() {
|
||||||
|
room_management_guide();
|
||||||
|
}
|
||||||
|
}
|
379
src/core/docs_best_practices.rs
Normal file
379
src/core/docs_best_practices.rs
Normal file
|
@ -0,0 +1,379 @@
|
||||||
|
//! Best Practices for Continuwuity Development
|
||||||
|
//!
|
||||||
|
//! This module provides best practices and guidelines for developing
|
||||||
|
//! with Continuwuity and our enhanced types.
|
||||||
|
|
||||||
|
use crate::types::*;
|
||||||
|
use crate::error::*;
|
||||||
|
|
||||||
|
/// Best Practice: Error Handling
|
||||||
|
///
|
||||||
|
/// Always use our enhanced error types for better user experience.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Use Enhanced Errors**: Always use `EnhancedError` for user-facing errors
|
||||||
|
/// 2. **Provide Context**: Include relevant context in error messages
|
||||||
|
/// 3. **Sanitize Logs**: Use `sanitized_message()` for logging to avoid sensitive data
|
||||||
|
/// 4. **Return Proper Codes**: Ensure Matrix error codes are correct
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::error::*;
|
||||||
|
///
|
||||||
|
/// fn validate_room_id(room_id: &str) -> Result<(), EnhancedError> {
|
||||||
|
/// if room_id.is_empty() {
|
||||||
|
/// return Err(EnhancedError::validation_error("room_id", "Room ID cannot be empty"));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// if !room_id.starts_with('!') {
|
||||||
|
/// return Err(EnhancedError::validation_error("room_id", "Room ID must start with '!'"));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn error_handling_best_practices() {
|
||||||
|
// This function demonstrates error handling best practices
|
||||||
|
let _example_error = EnhancedError::validation_error("room_id", "Room ID cannot be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Best Practice: Room Management
|
||||||
|
///
|
||||||
|
/// Use enhanced types for room operations to ensure consistency.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Use Enhanced Types**: Always use `EnhancedRoomInfo` for room data
|
||||||
|
/// 2. **Validate Permissions**: Check power levels before operations
|
||||||
|
/// 3. **Handle State Changes**: Properly manage room state transitions
|
||||||
|
/// 4. **Log Important Events**: Log room creation, member changes, etc.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// fn can_user_send_message(room: &EnhancedRoomInfo, user_id: &str) -> bool {
|
||||||
|
/// room.can_send_message(user_id)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn is_user_admin(room: &EnhancedRoomInfo, user_id: &str) -> bool {
|
||||||
|
/// room.is_admin(user_id)
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn room_management_best_practices() {
|
||||||
|
// This function demonstrates room management best practices
|
||||||
|
let room = EnhancedRoomInfo::new("!example:example.com".to_string());
|
||||||
|
let _can_send = room.can_send_message("@user:example.com");
|
||||||
|
let _is_admin = room.is_admin("@admin:example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Best Practice: Message Handling
|
||||||
|
///
|
||||||
|
/// Use enhanced message types for consistent message processing.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Use Enhanced Types**: Always use `EnhancedMessageContent` for messages
|
||||||
|
/// 2. **Handle Replies**: Properly process reply relationships
|
||||||
|
/// 3. **Support Threads**: Handle thread messages correctly
|
||||||
|
/// 4. **Validate Content**: Check message content before processing
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// fn process_message(message: &EnhancedMessageContent) -> Result<(), EnhancedError> {
|
||||||
|
/// if message.body.is_empty() {
|
||||||
|
/// return Err(EnhancedError::validation_error("body", "Message body cannot be empty"));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// if message.is_reply() {
|
||||||
|
/// // Handle reply logic
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// if message.is_thread() {
|
||||||
|
/// // Handle thread logic
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn message_handling_best_practices() {
|
||||||
|
// This function demonstrates message handling best practices
|
||||||
|
let message = EnhancedMessageContent::new_text("Hello, world!".to_string());
|
||||||
|
let _is_reply = message.is_reply();
|
||||||
|
let _is_thread = message.is_thread();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Best Practice: User Management
|
||||||
|
///
|
||||||
|
/// Use enhanced user types for consistent user operations.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Use Enhanced Types**: Always use `EnhancedUserInfo` for user data
|
||||||
|
/// 2. **Check Membership**: Verify user membership before operations
|
||||||
|
/// 3. **Handle Permissions**: Check user permissions appropriately
|
||||||
|
/// 4. **Update Presence**: Keep user presence information current
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// fn can_user_access_room(user: &EnhancedUserInfo, room: &EnhancedRoomInfo) -> bool {
|
||||||
|
/// user.is_member() && room.can_send_message(&user.user_id)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn is_user_moderator(user: &EnhancedUserInfo) -> bool {
|
||||||
|
/// user.is_moderator()
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn user_management_best_practices() {
|
||||||
|
// This function demonstrates user management best practices
|
||||||
|
let user = EnhancedUserInfo::new("@user:example.com".to_string());
|
||||||
|
let _is_member = user.is_member();
|
||||||
|
let _is_moderator = user.is_moderator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Best Practice: Power Level Management
|
||||||
|
///
|
||||||
|
/// Properly manage power levels for room permissions.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Use Default Values**: Start with sensible defaults
|
||||||
|
/// 2. **Document Changes**: Log power level changes
|
||||||
|
/// 3. **Validate Levels**: Ensure power levels are within valid ranges
|
||||||
|
/// 4. **Handle Inheritance**: Properly handle power level inheritance
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
/// use std::collections::HashMap;
|
||||||
|
///
|
||||||
|
/// fn set_user_power_level(power_levels: &mut PowerLevels, user_id: &str, level: i32) -> Result<(), EnhancedError> {
|
||||||
|
/// if level < -1 || level > 100 {
|
||||||
|
/// return Err(EnhancedError::validation_error("power_level", "Power level must be between -1 and 100"));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// power_levels.users.insert(user_id.to_string(), level);
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn power_level_management_best_practices() {
|
||||||
|
// This function demonstrates power level management best practices
|
||||||
|
let mut power_levels = PowerLevels::default();
|
||||||
|
power_levels.users.insert("@user:example.com".to_string(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Best Practice: Federation Handling
|
||||||
|
///
|
||||||
|
/// Properly handle federation operations with enhanced error types.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Use Enhanced Errors**: Use `EnhancedError::federation_error` for federation issues
|
||||||
|
/// 2. **Handle Timeouts**: Implement proper timeout handling
|
||||||
|
/// 3. **Log Federation Events**: Log important federation operations
|
||||||
|
/// 4. **Validate Responses**: Validate federation responses before processing
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::error::*;
|
||||||
|
///
|
||||||
|
/// async fn send_federation_request(server: &str, data: &[u8]) -> Result<(), EnhancedError> {
|
||||||
|
/// // Simulate federation request
|
||||||
|
/// if server.is_empty() {
|
||||||
|
/// return Err(EnhancedError::federation_error("unknown", "Server name cannot be empty"));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Handle federation logic here
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn federation_handling_best_practices() {
|
||||||
|
// This function demonstrates federation handling best practices
|
||||||
|
let _example_error = EnhancedError::federation_error("matrix.org", "Connection timeout");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Best Practice: Configuration Management
|
||||||
|
///
|
||||||
|
/// Use enhanced error types for configuration validation.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Validate Early**: Validate configuration at startup
|
||||||
|
/// 2. **Use Enhanced Errors**: Use `EnhancedError::config_error` for config issues
|
||||||
|
/// 3. **Provide Context**: Include field names in error messages
|
||||||
|
/// 4. **Handle Defaults**: Provide sensible defaults where possible
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::error::*;
|
||||||
|
///
|
||||||
|
/// fn validate_config_field(field_name: &str, value: &str) -> Result<(), EnhancedError> {
|
||||||
|
/// if value.is_empty() {
|
||||||
|
/// return Err(EnhancedError::config_error(field_name, "Value cannot be empty"));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn configuration_management_best_practices() {
|
||||||
|
// This function demonstrates configuration management best practices
|
||||||
|
let _example_error = EnhancedError::config_error("database_url", "Invalid format");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Best Practice: Database Operations
|
||||||
|
///
|
||||||
|
/// Use enhanced error types for database operations.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Use Enhanced Errors**: Use `EnhancedError::database_error` for DB issues
|
||||||
|
/// 2. **Include Operation Context**: Specify the operation that failed
|
||||||
|
/// 3. **Handle Connections**: Properly handle database connection issues
|
||||||
|
/// 4. **Log Operations**: Log important database operations
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::error::*;
|
||||||
|
///
|
||||||
|
/// async fn save_user_data(user_id: &str, data: &[u8]) -> Result<(), EnhancedError> {
|
||||||
|
/// // Simulate database operation
|
||||||
|
/// if user_id.is_empty() {
|
||||||
|
/// return Err(EnhancedError::database_error("save_user_data", "User ID cannot be empty"));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Handle database logic here
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn database_operations_best_practices() {
|
||||||
|
// This function demonstrates database operations best practices
|
||||||
|
let _example_error = EnhancedError::database_error("save_user_data", "Connection lost");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Best Practice: Network Operations
|
||||||
|
///
|
||||||
|
/// Use enhanced error types for network operations.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Use Enhanced Errors**: Use `EnhancedError::network_error` for network issues
|
||||||
|
/// 2. **Specify Service**: Include the service that failed
|
||||||
|
/// 3. **Handle Timeouts**: Implement proper timeout handling
|
||||||
|
/// 4. **Retry Logic**: Implement appropriate retry logic
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::error::*;
|
||||||
|
///
|
||||||
|
/// async fn make_http_request(url: &str) -> Result<(), EnhancedError> {
|
||||||
|
/// if url.is_empty() {
|
||||||
|
/// return Err(EnhancedError::network_error("http_client", "URL cannot be empty"));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Handle HTTP request logic here
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn network_operations_best_practices() {
|
||||||
|
// This function demonstrates network operations best practices
|
||||||
|
let _example_error = EnhancedError::network_error("http_client", "Connection timeout");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Best Practice: Rate Limiting
|
||||||
|
///
|
||||||
|
/// Use enhanced error types for rate limiting.
|
||||||
|
///
|
||||||
|
/// # Best Practices
|
||||||
|
///
|
||||||
|
/// 1. **Use Enhanced Errors**: Use `EnhancedError::rate_limit_exceeded` for rate limits
|
||||||
|
/// 2. **Include Resource**: Specify which resource was rate limited
|
||||||
|
/// 3. **Provide Retry Time**: Include when the user can retry
|
||||||
|
/// 4. **Log Rate Limits**: Log rate limit violations for monitoring
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::error::*;
|
||||||
|
///
|
||||||
|
/// fn check_rate_limit(resource: &str, user_id: &str) -> Result<(), EnhancedError> {
|
||||||
|
/// // Simulate rate limit check
|
||||||
|
/// if resource == "room_creation" {
|
||||||
|
/// return Err(EnhancedError::rate_limit_exceeded(resource, 60));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn rate_limiting_best_practices() {
|
||||||
|
// This function demonstrates rate limiting best practices
|
||||||
|
let _example_error = EnhancedError::rate_limit_exceeded("room_creation", 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_error_handling_best_practices() {
|
||||||
|
error_handling_best_practices();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_room_management_best_practices() {
|
||||||
|
room_management_best_practices();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_message_handling_best_practices() {
|
||||||
|
message_handling_best_practices();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_user_management_best_practices() {
|
||||||
|
user_management_best_practices();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_power_level_management_best_practices() {
|
||||||
|
power_level_management_best_practices();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_federation_handling_best_practices() {
|
||||||
|
federation_handling_best_practices();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_configuration_management_best_practices() {
|
||||||
|
configuration_management_best_practices();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_database_operations_best_practices() {
|
||||||
|
database_operations_best_practices();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_network_operations_best_practices() {
|
||||||
|
network_operations_best_practices();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rate_limiting_best_practices() {
|
||||||
|
rate_limiting_best_practices();
|
||||||
|
}
|
||||||
|
}
|
363
src/core/docs_examples.rs
Normal file
363
src/core/docs_examples.rs
Normal file
|
@ -0,0 +1,363 @@
|
||||||
|
//! Comprehensive Examples for Continuwuity
|
||||||
|
//!
|
||||||
|
//! This module provides practical examples for common Matrix operations
|
||||||
|
//! using our enhanced types and error handling.
|
||||||
|
|
||||||
|
use crate::types::*;
|
||||||
|
use crate::error::*;
|
||||||
|
|
||||||
|
/// Example: Creating a new room with enhanced types
|
||||||
|
///
|
||||||
|
/// This example shows how to create a new Matrix room using our enhanced
|
||||||
|
/// room creation request structure.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let room_request = EnhancedRoomCreateRequest {
|
||||||
|
/// name: Some("My Awesome Room".to_string()),
|
||||||
|
/// topic: Some("A room for awesome discussions".to_string()),
|
||||||
|
/// preset: Some(RoomPreset::PublicChat),
|
||||||
|
/// room_version: Some("10".to_string()),
|
||||||
|
/// is_direct: Some(false),
|
||||||
|
/// invite: Some(vec!["@alice:example.com".to_string()]),
|
||||||
|
/// initial_state: None,
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// // The room request is now ready to be sent to the Matrix server
|
||||||
|
/// ```
|
||||||
|
pub fn create_room_example() -> EnhancedRoomCreateRequest {
|
||||||
|
EnhancedRoomCreateRequest {
|
||||||
|
name: Some("Example Room".to_string()),
|
||||||
|
topic: Some("This is an example room created with enhanced types".to_string()),
|
||||||
|
preset: Some(RoomPreset::PublicChat),
|
||||||
|
room_version: Some("10".to_string()),
|
||||||
|
is_direct: Some(false),
|
||||||
|
invite: Some(vec!["@alice:example.com".to_string(), "@bob:example.com".to_string()]),
|
||||||
|
initial_state: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Example: Creating a text message with enhanced content
|
||||||
|
///
|
||||||
|
/// This example shows how to create a Matrix message using our enhanced
|
||||||
|
/// message content structure.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let message = EnhancedMessageContent::new_text("Hello, Matrix!".to_string());
|
||||||
|
///
|
||||||
|
/// // The message is ready to be sent to a room
|
||||||
|
/// ```
|
||||||
|
pub fn create_message_example() -> EnhancedMessageContent {
|
||||||
|
EnhancedMessageContent::new_text("Hello from Continuwuity!".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Example: Creating a reply message
|
||||||
|
///
|
||||||
|
/// This example shows how to create a reply to another message.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let mut reply = EnhancedMessageContent::new_text("This is a reply".to_string());
|
||||||
|
/// reply.relates_to = Some(RelatesTo {
|
||||||
|
/// in_reply_to: Some(InReplyTo {
|
||||||
|
/// event_id: "$original_event_id".to_string(),
|
||||||
|
/// }),
|
||||||
|
/// rel_type: None,
|
||||||
|
/// event_id: None,
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// // The reply is now properly linked to the original message
|
||||||
|
/// ```
|
||||||
|
pub fn create_reply_example() -> EnhancedMessageContent {
|
||||||
|
let mut reply = EnhancedMessageContent::new_text("This is a reply to your message".to_string());
|
||||||
|
reply.relates_to = Some(RelatesTo {
|
||||||
|
in_reply_to: Some(InReplyTo {
|
||||||
|
event_id: "$example_event_id".to_string(),
|
||||||
|
}),
|
||||||
|
rel_type: None,
|
||||||
|
event_id: None,
|
||||||
|
});
|
||||||
|
reply
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Example: Creating a thread message
|
||||||
|
///
|
||||||
|
/// This example shows how to create a message in a thread.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let mut thread_message = EnhancedMessageContent::new_text("Thread message".to_string());
|
||||||
|
/// thread_message.thread = Some(ThreadInfo {
|
||||||
|
/// event_id: "$thread_root_event_id".to_string(),
|
||||||
|
/// is_falling_back: None,
|
||||||
|
/// is_editing: None,
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// // The message is now part of a thread
|
||||||
|
/// ```
|
||||||
|
pub fn create_thread_message_example() -> EnhancedMessageContent {
|
||||||
|
let mut thread_message = EnhancedMessageContent::new_text("This is a thread message".to_string());
|
||||||
|
thread_message.thread = Some(ThreadInfo {
|
||||||
|
event_id: "$thread_root_event_id".to_string(),
|
||||||
|
is_falling_back: None,
|
||||||
|
is_editing: None,
|
||||||
|
});
|
||||||
|
thread_message
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Example: Setting up room power levels
|
||||||
|
///
|
||||||
|
/// This example shows how to configure power levels for a room.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
/// use std::collections::HashMap;
|
||||||
|
///
|
||||||
|
/// let mut power_levels = PowerLevels::default();
|
||||||
|
/// power_levels.users.insert("@admin:example.com".to_string(), 100);
|
||||||
|
/// power_levels.users.insert("@moderator:example.com".to_string(), 50);
|
||||||
|
/// power_levels.events_default = 0; // Anyone can send messages
|
||||||
|
/// power_levels.state_default = 50; // Only moderators can change state
|
||||||
|
///
|
||||||
|
/// // Power levels are now configured
|
||||||
|
/// ```
|
||||||
|
pub fn setup_power_levels_example() -> PowerLevels {
|
||||||
|
let mut power_levels = PowerLevels::default();
|
||||||
|
power_levels.users.insert("@admin:example.com".to_string(), 100);
|
||||||
|
power_levels.users.insert("@moderator:example.com".to_string(), 50);
|
||||||
|
power_levels.users.insert("@user:example.com".to_string(), 0);
|
||||||
|
power_levels.events_default = 0; // Anyone can send messages
|
||||||
|
power_levels.state_default = 50; // Only moderators can change state
|
||||||
|
power_levels.ban = 50; // Moderators can ban users
|
||||||
|
power_levels.kick = 50; // Moderators can kick users
|
||||||
|
power_levels
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Example: Creating a user profile
|
||||||
|
///
|
||||||
|
/// This example shows how to create a user profile with enhanced information.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let user_profile = EnhancedUserProfile {
|
||||||
|
/// user_id: "@alice:example.com".to_string(),
|
||||||
|
/// display_name: Some("Alice".to_string()),
|
||||||
|
/// avatar_url: Some("mxc://example.com/avatar123".to_string()),
|
||||||
|
/// is_online: true,
|
||||||
|
/// last_seen: Some(1640995200), // Unix timestamp
|
||||||
|
/// presence: PresenceState::Online,
|
||||||
|
/// status_msg: Some("Working on Matrix stuff".to_string()),
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// // User profile is now complete
|
||||||
|
/// ```
|
||||||
|
pub fn create_user_profile_example() -> EnhancedUserProfile {
|
||||||
|
EnhancedUserProfile {
|
||||||
|
user_id: "@alice:example.com".to_string(),
|
||||||
|
display_name: Some("Alice".to_string()),
|
||||||
|
avatar_url: Some("mxc://example.com/avatar123".to_string()),
|
||||||
|
is_online: true,
|
||||||
|
last_seen: Some(1640995200), // Unix timestamp
|
||||||
|
presence: PresenceState::Online,
|
||||||
|
status_msg: Some("Working on Matrix stuff".to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Example: Error handling with enhanced errors
|
||||||
|
///
|
||||||
|
/// This example shows how to use our enhanced error handling for better
|
||||||
|
/// user experience and debugging.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::error::*;
|
||||||
|
///
|
||||||
|
/// // Create a user-friendly error
|
||||||
|
/// let error = EnhancedError::room_not_found("!nonexistent:example.com");
|
||||||
|
///
|
||||||
|
/// // Get user-friendly message
|
||||||
|
/// let user_message = error.user_message();
|
||||||
|
/// println!("User sees: {}", user_message);
|
||||||
|
///
|
||||||
|
/// // Get sanitized message for logging
|
||||||
|
/// let log_message = error.sanitized_message();
|
||||||
|
/// println!("Log shows: {}", log_message);
|
||||||
|
///
|
||||||
|
/// // Get Matrix error code
|
||||||
|
/// let matrix_code = error.matrix_error_code();
|
||||||
|
/// println!("Matrix error code: {}", matrix_code);
|
||||||
|
/// ```
|
||||||
|
pub fn error_handling_example() -> EnhancedError {
|
||||||
|
let error = EnhancedError::room_not_found("!example:example.com");
|
||||||
|
|
||||||
|
// Demonstrate different error message types
|
||||||
|
let _user_message = error.user_message();
|
||||||
|
let _log_message = error.sanitized_message();
|
||||||
|
let _matrix_code = error.matrix_error_code();
|
||||||
|
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Example: Room member management
|
||||||
|
///
|
||||||
|
/// This example shows how to manage room members using enhanced types.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let member = EnhancedRoomMember {
|
||||||
|
/// user_id: "@alice:example.com".to_string(),
|
||||||
|
/// display_name: Some("Alice".to_string()),
|
||||||
|
/// avatar_url: Some("mxc://example.com/avatar123".to_string()),
|
||||||
|
/// membership: MembershipState::Join,
|
||||||
|
/// power_level: 50,
|
||||||
|
/// is_direct: false,
|
||||||
|
/// third_party_invite: None,
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// // Member information is now available
|
||||||
|
/// ```
|
||||||
|
pub fn room_member_example() -> EnhancedRoomMember {
|
||||||
|
EnhancedRoomMember {
|
||||||
|
user_id: "@alice:example.com".to_string(),
|
||||||
|
display_name: Some("Alice".to_string()),
|
||||||
|
avatar_url: Some("mxc://example.com/avatar123".to_string()),
|
||||||
|
membership: MembershipState::Join,
|
||||||
|
power_level: 50,
|
||||||
|
is_direct: false,
|
||||||
|
third_party_invite: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Example: Room summary for listings
|
||||||
|
///
|
||||||
|
/// This example shows how to create a room summary for display in room lists.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use conduwuit_core::types::*;
|
||||||
|
///
|
||||||
|
/// let room_summary = EnhancedRoomSummary {
|
||||||
|
/// room_id: "!room123:example.com".to_string(),
|
||||||
|
/// name: Some("General Discussion".to_string()),
|
||||||
|
/// topic: Some("A place for general chat".to_string()),
|
||||||
|
/// avatar_url: Some("mxc://example.com/room_avatar".to_string()),
|
||||||
|
/// member_count: 42,
|
||||||
|
/// is_public: true,
|
||||||
|
/// last_activity: 1640995200,
|
||||||
|
/// unread_count: 5,
|
||||||
|
/// highlight_count: 2,
|
||||||
|
/// notification_count: 7,
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// // Room summary is ready for display
|
||||||
|
/// ```
|
||||||
|
pub fn room_summary_example() -> EnhancedRoomSummary {
|
||||||
|
EnhancedRoomSummary {
|
||||||
|
room_id: "!room123:example.com".to_string(),
|
||||||
|
name: Some("General Discussion".to_string()),
|
||||||
|
topic: Some("A place for general chat".to_string()),
|
||||||
|
avatar_url: Some("mxc://example.com/room_avatar".to_string()),
|
||||||
|
member_count: 42,
|
||||||
|
is_public: true,
|
||||||
|
last_activity: 1640995200,
|
||||||
|
unread_count: 5,
|
||||||
|
highlight_count: 2,
|
||||||
|
notification_count: 7,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_room_example() {
|
||||||
|
let room_request = create_room_example();
|
||||||
|
assert_eq!(room_request.name, Some("Example Room".to_string()));
|
||||||
|
assert_eq!(room_request.preset, Some(RoomPreset::PublicChat));
|
||||||
|
assert!(room_request.invite.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_message_example() {
|
||||||
|
let message = create_message_example();
|
||||||
|
assert_eq!(message.msgtype, MessageType::Text);
|
||||||
|
assert_eq!(message.body, "Hello from Continuwuity!");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_reply_example() {
|
||||||
|
let reply = create_reply_example();
|
||||||
|
assert!(reply.is_reply());
|
||||||
|
assert!(reply.relates_to.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_thread_message_example() {
|
||||||
|
let thread_message = create_thread_message_example();
|
||||||
|
assert!(thread_message.is_thread());
|
||||||
|
assert!(thread_message.thread.is_some());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_setup_power_levels_example() {
|
||||||
|
let power_levels = setup_power_levels_example();
|
||||||
|
assert_eq!(power_levels.users.len(), 3);
|
||||||
|
assert_eq!(power_levels.events_default, 0);
|
||||||
|
assert_eq!(power_levels.state_default, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_user_profile_example() {
|
||||||
|
let profile = create_user_profile_example();
|
||||||
|
assert_eq!(profile.user_id, "@alice:example.com");
|
||||||
|
assert_eq!(profile.presence, PresenceState::Online);
|
||||||
|
assert!(profile.is_online);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_error_handling_example() {
|
||||||
|
let error = error_handling_example();
|
||||||
|
assert_eq!(error.matrix_error_code(), "M_NOT_FOUND");
|
||||||
|
assert_eq!(error.http_status_code(), 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_room_member_example() {
|
||||||
|
let member = room_member_example();
|
||||||
|
assert_eq!(member.user_id, "@alice:example.com");
|
||||||
|
assert_eq!(member.membership, MembershipState::Join);
|
||||||
|
assert_eq!(member.power_level, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_room_summary_example() {
|
||||||
|
let summary = room_summary_example();
|
||||||
|
assert_eq!(summary.room_id, "!room123:example.com");
|
||||||
|
assert_eq!(summary.member_count, 42);
|
||||||
|
assert!(summary.is_public);
|
||||||
|
}
|
||||||
|
}
|
449
src/core/types_enhanced.rs
Normal file
449
src/core/types_enhanced.rs
Normal file
|
@ -0,0 +1,449 @@
|
||||||
|
// Enhanced Type Definitions for Continuwuity
|
||||||
|
// Contributed from our chat-system improvements
|
||||||
|
// Provides cleaner, more focused type definitions for Matrix operations
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
/// Enhanced room information with better organization
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct EnhancedRoomInfo {
|
||||||
|
pub room_id: String,
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub topic: Option<String>,
|
||||||
|
pub avatar_url: Option<String>,
|
||||||
|
pub member_count: u32,
|
||||||
|
pub is_public: bool,
|
||||||
|
pub join_rule: JoinRule,
|
||||||
|
pub power_levels: PowerLevels,
|
||||||
|
pub creation_time: u64,
|
||||||
|
pub last_activity: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enhanced user information
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct EnhancedUserInfo {
|
||||||
|
pub user_id: String,
|
||||||
|
pub display_name: Option<String>,
|
||||||
|
pub avatar_url: Option<String>,
|
||||||
|
pub is_online: bool,
|
||||||
|
pub last_seen: Option<u64>,
|
||||||
|
pub power_level: i32,
|
||||||
|
pub membership_state: MembershipState,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Join rules for rooms
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum JoinRule {
|
||||||
|
#[serde(rename = "public")]
|
||||||
|
Public,
|
||||||
|
#[serde(rename = "invite")]
|
||||||
|
Invite,
|
||||||
|
#[serde(rename = "private")]
|
||||||
|
Private,
|
||||||
|
#[serde(rename = "knock")]
|
||||||
|
Knock,
|
||||||
|
#[serde(rename = "knock_restricted")]
|
||||||
|
KnockRestricted,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Membership states
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum MembershipState {
|
||||||
|
#[serde(rename = "invite")]
|
||||||
|
Invite,
|
||||||
|
#[serde(rename = "join")]
|
||||||
|
Join,
|
||||||
|
#[serde(rename = "knock")]
|
||||||
|
Knock,
|
||||||
|
#[serde(rename = "leave")]
|
||||||
|
Leave,
|
||||||
|
#[serde(rename = "ban")]
|
||||||
|
Ban,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Power levels for room permissions
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct PowerLevels {
|
||||||
|
pub users: HashMap<String, i32>,
|
||||||
|
pub events: HashMap<String, i32>,
|
||||||
|
pub events_default: i32,
|
||||||
|
pub state_default: i32,
|
||||||
|
pub ban: i32,
|
||||||
|
pub kick: i32,
|
||||||
|
pub redact: i32,
|
||||||
|
pub invite: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PowerLevels {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
users: HashMap::new(),
|
||||||
|
events: HashMap::new(),
|
||||||
|
events_default: 0,
|
||||||
|
state_default: 50,
|
||||||
|
ban: 50,
|
||||||
|
kick: 50,
|
||||||
|
redact: 50,
|
||||||
|
invite: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enhanced message content with better structure
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct EnhancedMessageContent {
|
||||||
|
pub msgtype: MessageType,
|
||||||
|
pub body: String,
|
||||||
|
pub formatted_body: Option<String>,
|
||||||
|
pub format: Option<String>,
|
||||||
|
pub relates_to: Option<RelatesTo>,
|
||||||
|
pub mentions: Option<Mentions>,
|
||||||
|
pub thread: Option<ThreadInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Message types
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum MessageType {
|
||||||
|
#[serde(rename = "m.text")]
|
||||||
|
Text,
|
||||||
|
#[serde(rename = "m.notice")]
|
||||||
|
Notice,
|
||||||
|
#[serde(rename = "m.emote")]
|
||||||
|
Emote,
|
||||||
|
#[serde(rename = "m.image")]
|
||||||
|
Image,
|
||||||
|
#[serde(rename = "m.file")]
|
||||||
|
File,
|
||||||
|
#[serde(rename = "m.video")]
|
||||||
|
Video,
|
||||||
|
#[serde(rename = "m.audio")]
|
||||||
|
Audio,
|
||||||
|
#[serde(rename = "m.location")]
|
||||||
|
Location,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Relates to information for replies/threads
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct RelatesTo {
|
||||||
|
#[serde(rename = "m.in_reply_to")]
|
||||||
|
pub in_reply_to: Option<InReplyTo>,
|
||||||
|
#[serde(rename = "rel_type")]
|
||||||
|
pub rel_type: Option<String>,
|
||||||
|
#[serde(rename = "event_id")]
|
||||||
|
pub event_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// In-reply-to information
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct InReplyTo {
|
||||||
|
pub event_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mentions in messages
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Mentions {
|
||||||
|
pub user_ids: Vec<String>,
|
||||||
|
pub room: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Thread information
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ThreadInfo {
|
||||||
|
pub event_id: String,
|
||||||
|
pub is_falling_back: Option<bool>,
|
||||||
|
pub is_editing: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enhanced room creation request
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct EnhancedRoomCreateRequest {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub topic: Option<String>,
|
||||||
|
pub preset: Option<RoomPreset>,
|
||||||
|
pub room_version: Option<String>,
|
||||||
|
pub is_direct: Option<bool>,
|
||||||
|
pub invite: Option<Vec<String>>,
|
||||||
|
pub initial_state: Option<Vec<InitialStateEvent>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Room presets
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum RoomPreset {
|
||||||
|
#[serde(rename = "private_chat")]
|
||||||
|
PrivateChat,
|
||||||
|
#[serde(rename = "trusted_private_chat")]
|
||||||
|
TrustedPrivateChat,
|
||||||
|
#[serde(rename = "public_chat")]
|
||||||
|
PublicChat,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initial state events for room creation
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct InitialStateEvent {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub event_type: String,
|
||||||
|
pub state_key: String,
|
||||||
|
pub content: serde_json::Value,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enhanced room member information
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct EnhancedRoomMember {
|
||||||
|
pub user_id: String,
|
||||||
|
pub display_name: Option<String>,
|
||||||
|
pub avatar_url: Option<String>,
|
||||||
|
pub membership: MembershipState,
|
||||||
|
pub power_level: i32,
|
||||||
|
pub is_direct: bool,
|
||||||
|
pub third_party_invite: Option<ThirdPartyInvite>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Third party invite information
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ThirdPartyInvite {
|
||||||
|
pub display_name: String,
|
||||||
|
pub signed: SignedInvite,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Signed invite information
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct SignedInvite {
|
||||||
|
pub mxid: String,
|
||||||
|
pub token: String,
|
||||||
|
pub signatures: HashMap<String, HashMap<String, String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enhanced room summary for listings
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct EnhancedRoomSummary {
|
||||||
|
pub room_id: String,
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub topic: Option<String>,
|
||||||
|
pub avatar_url: Option<String>,
|
||||||
|
pub member_count: u32,
|
||||||
|
pub is_public: bool,
|
||||||
|
pub last_activity: u64,
|
||||||
|
pub unread_count: u32,
|
||||||
|
pub highlight_count: u32,
|
||||||
|
pub notification_count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enhanced user profile
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct EnhancedUserProfile {
|
||||||
|
pub user_id: String,
|
||||||
|
pub display_name: Option<String>,
|
||||||
|
pub avatar_url: Option<String>,
|
||||||
|
pub is_online: bool,
|
||||||
|
pub last_seen: Option<u64>,
|
||||||
|
pub presence: PresenceState,
|
||||||
|
pub status_msg: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Presence states
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum PresenceState {
|
||||||
|
#[serde(rename = "online")]
|
||||||
|
Online,
|
||||||
|
#[serde(rename = "offline")]
|
||||||
|
Offline,
|
||||||
|
#[serde(rename = "unavailable")]
|
||||||
|
Unavailable,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper functions for enhanced types
|
||||||
|
impl EnhancedRoomInfo {
|
||||||
|
pub fn new(room_id: String) -> Self {
|
||||||
|
Self {
|
||||||
|
room_id,
|
||||||
|
name: None,
|
||||||
|
topic: None,
|
||||||
|
avatar_url: None,
|
||||||
|
member_count: 0,
|
||||||
|
is_public: false,
|
||||||
|
join_rule: JoinRule::Invite,
|
||||||
|
power_levels: PowerLevels::default(),
|
||||||
|
creation_time: 0,
|
||||||
|
last_activity: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_admin(&self, user_id: &str) -> bool {
|
||||||
|
self.power_levels.users.get(user_id)
|
||||||
|
.map(|level| *level >= 100)
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn can_send_message(&self, user_id: &str) -> bool {
|
||||||
|
let user_level = self.power_levels.users.get(user_id).unwrap_or(&0);
|
||||||
|
*user_level >= self.power_levels.events_default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EnhancedUserInfo {
|
||||||
|
pub fn new(user_id: String) -> Self {
|
||||||
|
Self {
|
||||||
|
user_id,
|
||||||
|
display_name: None,
|
||||||
|
avatar_url: None,
|
||||||
|
is_online: false,
|
||||||
|
last_seen: None,
|
||||||
|
power_level: 0,
|
||||||
|
membership_state: MembershipState::Leave,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_member(&self) -> bool {
|
||||||
|
self.membership_state == MembershipState::Join
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_moderator(&self) -> bool {
|
||||||
|
self.power_level >= 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EnhancedMessageContent {
|
||||||
|
pub fn new_text(body: String) -> Self {
|
||||||
|
Self {
|
||||||
|
msgtype: MessageType::Text,
|
||||||
|
body,
|
||||||
|
formatted_body: None,
|
||||||
|
format: None,
|
||||||
|
relates_to: None,
|
||||||
|
mentions: None,
|
||||||
|
thread: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_notice(body: String) -> Self {
|
||||||
|
Self {
|
||||||
|
msgtype: MessageType::Notice,
|
||||||
|
body,
|
||||||
|
formatted_body: None,
|
||||||
|
format: None,
|
||||||
|
relates_to: None,
|
||||||
|
mentions: None,
|
||||||
|
thread: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_reply(&self) -> bool {
|
||||||
|
self.relates_to.as_ref()
|
||||||
|
.and_then(|r| r.in_reply_to.as_ref())
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_thread(&self) -> bool {
|
||||||
|
self.thread.is_some()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enhanced_room_info_creation() {
|
||||||
|
let room = EnhancedRoomInfo::new("!test:example.com".to_string());
|
||||||
|
assert_eq!(room.room_id, "!test:example.com");
|
||||||
|
assert_eq!(room.member_count, 0);
|
||||||
|
assert_eq!(room.join_rule, JoinRule::Invite);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enhanced_user_info_creation() {
|
||||||
|
let user = EnhancedUserInfo::new("@user:example.com".to_string());
|
||||||
|
assert_eq!(user.user_id, "@user:example.com");
|
||||||
|
assert!(!user.is_online);
|
||||||
|
assert_eq!(user.membership_state, MembershipState::Leave);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enhanced_message_content_creation() {
|
||||||
|
let message = EnhancedMessageContent::new_text("Hello world".to_string());
|
||||||
|
assert_eq!(message.msgtype, MessageType::Text);
|
||||||
|
assert_eq!(message.body, "Hello world");
|
||||||
|
assert!(!message.is_reply());
|
||||||
|
assert!(!message.is_thread());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_room_admin_check() {
|
||||||
|
let mut room = EnhancedRoomInfo::new("!test:example.com".to_string());
|
||||||
|
room.power_levels.users.insert("@admin:example.com".to_string(), 100);
|
||||||
|
room.power_levels.users.insert("@user:example.com".to_string(), 0);
|
||||||
|
|
||||||
|
assert!(room.is_admin("@admin:example.com"));
|
||||||
|
assert!(!room.is_admin("@user:example.com"));
|
||||||
|
assert!(!room.is_admin("@nonexistent:example.com"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_room_message_permission() {
|
||||||
|
let mut room = EnhancedRoomInfo::new("!test:example.com".to_string());
|
||||||
|
room.power_levels.events_default = 0;
|
||||||
|
room.power_levels.users.insert("@user:example.com".to_string(), 0);
|
||||||
|
room.power_levels.users.insert("@muted:example.com".to_string(), -1);
|
||||||
|
|
||||||
|
assert!(room.can_send_message("@user:example.com"));
|
||||||
|
assert!(!room.can_send_message("@muted:example.com"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_user_membership_check() {
|
||||||
|
let mut user = EnhancedUserInfo::new("@user:example.com".to_string());
|
||||||
|
user.membership_state = MembershipState::Join;
|
||||||
|
assert!(user.is_member());
|
||||||
|
|
||||||
|
user.membership_state = MembershipState::Leave;
|
||||||
|
assert!(!user.is_member());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_user_moderator_check() {
|
||||||
|
let mut user = EnhancedUserInfo::new("@user:example.com".to_string());
|
||||||
|
user.power_level = 50;
|
||||||
|
assert!(user.is_moderator());
|
||||||
|
|
||||||
|
user.power_level = 49;
|
||||||
|
assert!(!user.is_moderator());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_message_reply_check() {
|
||||||
|
let mut message = EnhancedMessageContent::new_text("Reply".to_string());
|
||||||
|
message.relates_to = Some(RelatesTo {
|
||||||
|
in_reply_to: Some(InReplyTo {
|
||||||
|
event_id: "$event123".to_string(),
|
||||||
|
}),
|
||||||
|
rel_type: None,
|
||||||
|
event_id: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert!(message.is_reply());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_message_thread_check() {
|
||||||
|
let mut message = EnhancedMessageContent::new_text("Thread message".to_string());
|
||||||
|
message.thread = Some(ThreadInfo {
|
||||||
|
event_id: "$thread123".to_string(),
|
||||||
|
is_falling_back: None,
|
||||||
|
is_editing: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert!(message.is_thread());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_power_levels_default() {
|
||||||
|
let power_levels = PowerLevels::default();
|
||||||
|
assert_eq!(power_levels.events_default, 0);
|
||||||
|
assert_eq!(power_levels.state_default, 50);
|
||||||
|
assert_eq!(power_levels.ban, 50);
|
||||||
|
assert_eq!(power_levels.kick, 50);
|
||||||
|
assert_eq!(power_levels.redact, 50);
|
||||||
|
assert_eq!(power_levels.invite, 0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue