pub mod at;
pub mod ffi;
pub mod image;
pub mod meta;
use crate::message::at::At;
use crate::message::meta::{Anonymous, MessageMetadata, MetaMessage, Reply};
use crate::Text;
use core::slice;
use image::Image;
use ricq::msg::elem::RQElem;
use ricq::msg::{MessageElem, PushElem};
use ricq::structs::{FriendMessage, GroupMessage};
use serde::{Deserialize, Serialize};
use std::fmt::{Debug, Formatter};
use std::vec;
#[derive(Serialize, Deserialize, Clone, Default)]
pub struct MessageChain {
meta: MessageMetadata,
value: Vec<MessageElement>,
}
impl MessageChain {
pub fn iter(&self) -> slice::Iter<'_, MessageElement> {
self.into_iter()
}
pub fn metadata(&self) -> &MessageMetadata {
&self.meta
}
pub fn to_json(&self) -> String {
serde_json::to_string(self).expect("Serializing error")
}
pub fn from_json(s: &str) -> serde_json::Result<Self> {
serde_json::from_str(s)
}
}
impl MetaMessage for MessageChain {
fn metadata(&self) -> &MessageMetadata {
&self.meta
}
}
impl ToString for MessageChain {
fn to_string(&self) -> String {
self.iter().map(|value| value.to_string()).collect()
}
}
impl Debug for MessageChain {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.to_string())
}
}
impl IntoIterator for MessageChain {
type Item = MessageElement;
type IntoIter = vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.value.into_iter()
}
}
impl<'a> IntoIterator for &'a MessageChain {
type Item = &'a MessageElement;
type IntoIter = slice::Iter<'a, MessageElement>;
fn into_iter(self) -> Self::IntoIter {
self.value.iter()
}
}
impl From<GroupMessage> for MessageChain {
fn from(g: GroupMessage) -> Self {
let mut ran = Self::from(g.elements);
ran.meta = MessageMetadata {
seqs: g.seqs,
rands: g.rands,
time: g.time,
sender: g.from_uin,
..ran.meta
};
ran
}
}
impl From<FriendMessage> for MessageChain {
fn from(f: FriendMessage) -> Self {
let mut ran = Self::from(f.elements);
ran.meta = MessageMetadata {
seqs: f.seqs,
rands: f.rands,
time: f.time,
sender: f.from_uin,
..ran.meta
};
ran
}
}
impl From<Vec<MessageElement>> for MessageChain {
fn from(elems: Vec<MessageElement>) -> Self {
Self {
value: elems,
..Default::default()
}
}
}
impl From<ricq::msg::MessageChain> for MessageChain {
fn from(chain: ricq::msg::MessageChain) -> Self {
let mut iter = chain.0.into_iter();
let mut meta = MessageMetadata::default();
let mut value: Vec<MessageElement> = vec![];
for _ in 0..2 {
match iter.next() {
Some(MessageElem::AnonGroupMsg(msg)) => {
let rq = ricq::msg::elem::Anonymous::from(msg);
meta.anonymous = Some(Anonymous::from(rq));
}
Some(MessageElem::SrcMsg(src)) => {
let rq = ricq::msg::elem::Reply::from(src);
meta.reply = Some(Reply::from(rq));
}
Some(or) => {
let rq = ricq::msg::elem::RQElem::from(or);
value.push(MessageElement::from(rq));
}
None => {}
}
}
for val in iter {
let rq = ricq::msg::elem::RQElem::from(val);
value.push(MessageElement::from(rq));
}
Self { meta, value }
}
}
impl From<MessageChain> for ricq::msg::MessageChain {
fn from(chain: MessageChain) -> Self {
let mut rq = ricq::msg::MessageChain::default();
MessageChain::push_to(chain, &mut rq.0);
rq
}
}
impl PushElem for MessageChain {
fn push_to(elem: Self, vec: &mut Vec<MessageElem>) {
if let Some(reply) = elem.meta.reply {
let rq = ricq::msg::elem::Reply::from(reply);
vec.push(rq.into());
}
if let Some(ano) = elem.meta.anonymous {
let rq = ricq::msg::elem::Anonymous::from(ano);
vec.push(rq.into());
}
for value in elem.value {
MessageElement::push_to(value, vec);
}
}
}
#[derive(Serialize, Deserialize, Clone)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
pub enum MessageElement {
Text(String),
Image(Image),
At(At),
AtAll,
#[serde(skip)]
Unknown(RQElem),
}
impl ToString for MessageElement {
fn to_string(&self) -> String {
let mut s = String::new();
match self {
Self::Text(t) => s.push_str(t),
Self::Image(img) => s.push_str(&format!("$[Image:{}]", img.url())),
Self::At(At { target, display }) => {
s.push_str(&format!("$[At:{}({})]", display, target))
}
Self::AtAll => s.push_str("$[AtAll]"),
Self::Unknown(rq) => s.push_str(&rq.to_string()),
}
s
}
}
impl From<String> for MessageElement {
fn from(s: String) -> Self {
Self::Text(s)
}
}
impl From<MessageElement> for RQElem {
fn from(val: MessageElement) -> Self {
match val {
MessageElement::Text(s) => RQElem::Text(Text { content: s }),
MessageElement::Image(img) => match img {
Image::Friend(img) => RQElem::FriendImage(img),
Image::Group(img) => RQElem::GroupImage(img),
},
MessageElement::At(at) => RQElem::At(at.into()),
MessageElement::AtAll => RQElem::At(At::ALL.into()),
MessageElement::Unknown(rq) => rq,
}
}
}
impl From<RQElem> for MessageElement {
fn from(elem: RQElem) -> Self {
match elem {
RQElem::Text(Text { content }) => MessageElement::Text(content),
RQElem::GroupImage(img) => MessageElement::Image(Image::Group(img)),
RQElem::FriendImage(img) => MessageElement::Image(Image::Friend(img)),
RQElem::At(at) => {
if at.target == 0 {
MessageElement::AtAll
} else {
MessageElement::At(At {
target: at.target,
display: at.display,
})
}
}
or => Self::Unknown(or),
}
}
}
impl PushElem for MessageElement {
fn push_to(elem: Self, vec: &mut Vec<MessageElem>) {
match elem {
Self::Text(s) => PushElem::push_to(Text::new(s), vec),
Self::Image(img) => PushElem::push_to(img, vec),
Self::At(at) => PushElem::push_to(at, vec),
Self::AtAll => PushElem::push_to(At::ALL, vec),
Self::Unknown(_rq) => {}
}
}
}