agentlink-core 0.1.0

AgentLink SDK Core - Platform agnostic core library
Documentation
//! Friend Protocol Types

use serde::{Deserialize, Serialize};
use serde_json::Value;

use super::user::User;

/// 好友关系
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Friendship {
    pub id: String,
    pub user_id: String,
    pub friend_id: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub remark: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub group_id: Option<String>,
    pub is_favorite: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Value>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub can_view_moments: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub can_view_album: Option<bool>,
    pub friend_since: String,
    pub created_at: String,
    pub updated_at: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub friend: Option<User>,
    #[serde(default)]
    pub group: Option<FriendGroupInfo>,
}

/// 好友分组信息
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct FriendGroupInfo {
    pub id: Option<String>,
    pub name: Option<String>,
}

/// 好友列表响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FriendsListResponse {
    pub total: i32,
    pub friends: Vec<Friendship>,
}

/// 同步好友列表数据
/// 
/// Protocol: mqtt-events.md#sync_friend_list
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SyncFriendListData {
    pub friends: Vec<Friendship>,
    pub groups: Vec<FriendGroup>,
}

/// 好友请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FriendRequest {
    pub id: String,
    pub from_user_id: String,
    pub to_user_id: String,
    pub status: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub message: Option<String>,
    pub req_count: i32,
    pub last_req_at: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub responded_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub responded_message: Option<String>,
    pub expires_at: String,
    pub created_at: String,
    pub updated_at: String,
}

/// 好友请求列表响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FriendRequestsResponse {
    pub pending: i32,
    pub requests: Vec<FriendRequest>,
}

/// 同步好友请求列表数据
/// 
/// Protocol: mqtt-events.md#sync_friend_request_list
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SyncFriendRequestsData {
    pub requests: Vec<FriendRequest>,
    pub total: i32,
    pub sync_id: i64,
}

/// 发送好友请求
#[derive(Debug, Clone, Serialize)]
pub struct SendFriendRequest {
    pub to_user_id: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub message: Option<String>,
}

/// 响应好友请求
#[derive(Debug, Clone, Deserialize)]
pub struct RespondFriendRequest {
    pub request_id: String,
    pub accept: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub message: Option<String>,
}

// 自定义序列化:将 accept 布尔值转换为 action 字符串
impl Serialize for RespondFriendRequest {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        use serde::ser::SerializeStruct;

        let mut state = serializer.serialize_struct("RespondFriendRequest", 3)?;
        state.serialize_field("request_id", &self.request_id)?;
        state.serialize_field("action", if self.accept { "accepted" } else { "rejected" })?;
        state.serialize_field("message", &self.message)?;
        state.end()
    }
}

/// 好友分组
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FriendGroup {
    pub id: String,
    pub user_id: String,
    pub name: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub color: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub icon: Option<String>,
    pub sort_order: i32,
    pub created_at: String,
    pub updated_at: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub member_count: Option<i32>,
}

/// 创建好友分组请求
#[derive(Debug, Clone, Serialize)]
pub struct CreateFriendGroupRequest {
    pub name: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub color: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub icon: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub sort_order: Option<i32>,
}

/// 更新好友分组请求
#[derive(Debug, Clone, Serialize)]
pub struct UpdateFriendGroupRequest {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub color: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub icon: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub sort_order: Option<i32>,
}

/// 更新好友关系请求
#[derive(Debug, Clone, Serialize)]
pub struct UpdateFriendshipRequest {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub remark: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub group_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub is_favorite: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub can_view_moments: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub can_view_album: Option<bool>,
}