use std::{ops::Deref, sync::Arc};
use async_trait::async_trait;
use ricq::structs::{GroupMemberInfo, GroupMemberPermission};
use thiserror::Error;
use crate::{
client::{group::FetchGroupInfoError, group_member_list::FetchGroupMemberListError},
meta::selector::{OptionSelector, Selector},
Client,
};
box_error_impl!(
FetchGroupMemberInfoError,
FetchGroupMemberInfoErrorImpl,
"获取群成员信息失败。"
);
#[derive(Error, Debug)]
enum FetchGroupMemberInfoErrorImpl {
#[error("获取群信息失败")]
FetchGroupInfoError(#[from] FetchGroupInfoError),
#[error("获取群成员列表失败")]
FetchGroupMemberListError(#[from] FetchGroupMemberListError),
}
#[derive(Debug, Clone)]
pub struct GroupMember {
selector: GroupMemberSelector,
pub group_code: i64,
pub uin: i64,
pub gender: u8,
pub nickname: String,
pub card_name: String,
pub level: u16,
pub join_time: i64,
pub last_speak_time: i64,
pub special_title: String,
pub special_title_expire_time: i64,
pub shut_up_timestamp: i64,
pub permission: GroupMemberPermission,
}
impl GroupMember {
pub(crate) fn new(client: &Arc<Client>, info: GroupMemberInfo) -> Self {
Self {
selector: client.group(info.group_code).member(info.uin),
group_code: info.group_code,
uin: info.uin,
gender: info.gender,
nickname: info.nickname,
card_name: info.card_name,
level: info.level,
join_time: info.join_time,
last_speak_time: info.last_speak_time,
special_title: info.special_title,
special_title_expire_time: info.special_title_expire_time,
shut_up_timestamp: info.shut_up_timestamp,
permission: info.permission,
}
}
}
impl Deref for GroupMember {
type Target = GroupMemberSelector;
fn deref(&self) -> &Self::Target {
&self.selector
}
}
#[derive(Debug, Clone)]
pub struct GroupMemberSelector {
client: Arc<Client>,
pub group_code: i64,
pub uin: i64,
}
impl GroupMemberSelector {
pub(crate) fn new(client: Arc<Client>, group_code: i64, uin: i64) -> Self {
Self {
client,
group_code,
uin,
}
}
}
#[async_trait]
impl Selector for GroupMemberSelector {
type Target = Arc<GroupMember>;
type Error = FetchGroupMemberInfoError;
async fn flush(&self) -> &Self {
self.client
.group_member_lists
.make_dirty(&self.group_code)
.await;
self
}
fn as_client(&self) -> &Arc<Client> {
&self.client
}
}
#[async_trait]
impl OptionSelector for GroupMemberSelector {
async fn fetch(&self) -> Result<Option<Self::Target>, Self::Error> {
Ok(self
.client
.group_member_lists
.get(&self.client, &self.group_code)
.await?
.unwrap()
.members()
.get(&self.uin)
.cloned())
}
}