use super::*;
pub(super) fn decode_message(ev: RawEventJson) -> Event {
let is_group = ev.message_type.as_deref() == Some("group");
let peer = if is_group {
Peer::group(ev.group_id.unwrap_or(0))
} else if ev.sub_type.as_deref() == Some("group") {
Peer::temp(ev.user_id.unwrap_or(0))
} else {
Peer::friend(ev.user_id.unwrap_or(0))
};
let sender = Uin(ev.user_id.unwrap_or(0));
let self_id = Uin(ev.self_id);
let is_self = ev.post_type.as_deref() == Some("message_sent") || sender == self_id;
let id = MessageId { peer, seq: ev.message_seq.unwrap_or(0), onebot_id: ev.message_id };
let content: Message = match &ev.message {
Some(WireMessage::Array(segs)) => decode_segments(segs, peer),
Some(WireMessage::Cq(s)) => decode_cq_string(s, peer),
None => Vec::new(),
};
let raw = event_raw_value(&ev);
let member = if is_group {
ev.sender
.as_ref()
.map(|s| member_from_sender(s, sender, Uin(ev.group_id.unwrap_or(0))))
} else {
None
};
let friend = if is_group {
None
} else {
ev.sender.as_ref().map(|s| friend_from_sender(s, sender))
};
let anonymous = ev.anonymous.as_ref().map(|a| Anonymous {
id: a.id,
name: a.name.clone(),
flag: a.flag.clone(),
});
let target_id = ev.target_id.filter(|_| !is_group).map(Uin);
let message_style = ev.message_style.as_ref().map(|s| MessageStyle {
bubble_id: s.bubble_id,
pendant_id: s.pendant_id,
pal_type: s.pal_type,
raw: serde_json::to_value(s).unwrap_or(Value::Null),
});
Event::Message(Box::new(MessageEvent {
id,
peer,
sender,
self_id,
time: ev.time,
content,
is_self,
group: None,
member,
friend,
anonymous,
font: ev.font,
target_id,
message_style,
raw,
}))
}
fn member_from_sender(s: &crate::wire::WireSender, user: Uin, group: Uin) -> MemberInfo {
MemberInfo {
user,
group,
nickname: s.nickname.clone().unwrap_or_default(),
card: s.card.clone().unwrap_or_default(),
title: s.title.clone().unwrap_or_default(),
level: s.level.as_ref().and_then(|l| l.parse().ok()).unwrap_or(0),
role: match s.role.as_deref() {
Some("owner") => Role::Owner,
Some("admin") => Role::Admin,
_ => Role::Member,
},
sex: match s.sex.as_deref() {
Some("male") => Sex::Male,
Some("female") => Sex::Female,
_ => Sex::Unknown,
},
age: s.age,
join_time: 0,
last_sent_time: None,
mute_end_time: None,
area: s.area.clone().filter(|a| !a.is_empty()),
unfriendly: None,
title_expire_time: None,
card_changeable: None,
qq_level: None,
is_robot: None,
qage: None,
raw: serde_json::to_value(s).unwrap_or(Value::Null),
}
}
fn friend_from_sender(s: &crate::wire::WireSender, user: Uin) -> FriendInfo {
FriendInfo {
user,
nickname: s.nickname.clone().unwrap_or_default(),
sex: match s.sex.as_deref() {
Some("male") => Sex::Male,
Some("female") => Sex::Female,
_ => Sex::Unknown,
},
remark: String::new(),
qid: None,
category: None,
group: None,
birthday: None,
phone: None,
email: None,
login_days: None,
long_nick: None,
raw: serde_json::to_value(s).unwrap_or(Value::Null),
}
}