use layer_tl_types::{self as tl, Cursor, Deserializable};
use crate::{Client, InvocationError, PeerRef, update};
pub struct SearchBuilder {
peer: PeerRef,
query: String,
filter: tl::enums::MessagesFilter,
min_date: i32,
max_date: i32,
offset_id: i32,
add_offset: i32,
limit: i32,
max_id: i32,
min_id: i32,
from_id: Option<tl::enums::InputPeer>,
top_msg_id: Option<i32>,
}
impl SearchBuilder {
pub(crate) fn new(peer: PeerRef, query: String) -> Self {
Self {
peer,
query,
filter: tl::enums::MessagesFilter::InputMessagesFilterEmpty,
min_date: 0,
max_date: 0,
offset_id: 0,
add_offset: 0,
limit: 100,
max_id: 0,
min_id: 0,
from_id: None,
top_msg_id: None,
}
}
pub fn min_date(mut self, ts: i32) -> Self {
self.min_date = ts;
self
}
pub fn max_date(mut self, ts: i32) -> Self {
self.max_date = ts;
self
}
pub fn filter(mut self, f: tl::enums::MessagesFilter) -> Self {
self.filter = f;
self
}
pub fn limit(mut self, n: i32) -> Self {
self.limit = n;
self
}
pub fn offset_id(mut self, id: i32) -> Self {
self.offset_id = id;
self
}
pub fn add_offset(mut self, off: i32) -> Self {
self.add_offset = off;
self
}
pub fn max_id(mut self, id: i32) -> Self {
self.max_id = id;
self
}
pub fn min_id(mut self, id: i32) -> Self {
self.min_id = id;
self
}
pub fn sent_by_self(mut self) -> Self {
self.from_id = Some(tl::enums::InputPeer::PeerSelf);
self
}
pub fn from_peer(mut self, peer: tl::enums::InputPeer) -> Self {
self.from_id = Some(peer);
self
}
pub fn top_msg_id(mut self, id: i32) -> Self {
self.top_msg_id = Some(id);
self
}
pub async fn fetch(
self,
client: &Client,
) -> Result<Vec<update::IncomingMessage>, InvocationError> {
let peer = self.peer.resolve(client).await?;
let input_peer = client.inner.peer_cache.read().await.peer_to_input(&peer);
let req = tl::functions::messages::Search {
peer: input_peer,
q: self.query,
from_id: self.from_id,
saved_peer_id: None,
saved_reaction: None,
top_msg_id: self.top_msg_id,
filter: self.filter,
min_date: self.min_date,
max_date: self.max_date,
offset_id: self.offset_id,
add_offset: self.add_offset,
limit: self.limit,
max_id: self.max_id,
min_id: self.min_id,
hash: 0,
};
let body = client.rpc_call_raw(&req).await?;
let mut cur = Cursor::from_slice(&body);
let msgs = match tl::enums::messages::Messages::deserialize(&mut cur)? {
tl::enums::messages::Messages::Messages(m) => m.messages,
tl::enums::messages::Messages::Slice(m) => m.messages,
tl::enums::messages::Messages::ChannelMessages(m) => m.messages,
tl::enums::messages::Messages::NotModified(_) => vec![],
};
Ok(msgs
.into_iter()
.map(update::IncomingMessage::from_raw)
.collect())
}
}
pub struct GlobalSearchBuilder {
query: String,
filter: tl::enums::MessagesFilter,
min_date: i32,
max_date: i32,
offset_rate: i32,
offset_id: i32,
limit: i32,
folder_id: Option<i32>,
broadcasts_only: bool,
groups_only: bool,
users_only: bool,
}
impl GlobalSearchBuilder {
pub(crate) fn new(query: String) -> Self {
Self {
query,
filter: tl::enums::MessagesFilter::InputMessagesFilterEmpty,
min_date: 0,
max_date: 0,
offset_rate: 0,
offset_id: 0,
limit: 100,
folder_id: None,
broadcasts_only: false,
groups_only: false,
users_only: false,
}
}
pub fn folder_id(mut self, id: i32) -> Self {
self.folder_id = Some(id);
self
}
pub fn broadcasts_only(mut self, v: bool) -> Self {
self.broadcasts_only = v;
self
}
pub fn groups_only(mut self, v: bool) -> Self {
self.groups_only = v;
self
}
pub fn users_only(mut self, v: bool) -> Self {
self.users_only = v;
self
}
pub fn filter(mut self, f: tl::enums::MessagesFilter) -> Self {
self.filter = f;
self
}
pub fn min_date(mut self, ts: i32) -> Self {
self.min_date = ts;
self
}
pub fn max_date(mut self, ts: i32) -> Self {
self.max_date = ts;
self
}
pub fn offset_rate(mut self, r: i32) -> Self {
self.offset_rate = r;
self
}
pub fn offset_id(mut self, id: i32) -> Self {
self.offset_id = id;
self
}
pub fn limit(mut self, n: i32) -> Self {
self.limit = n;
self
}
pub async fn fetch(
self,
client: &Client,
) -> Result<Vec<update::IncomingMessage>, InvocationError> {
let req = tl::functions::messages::SearchGlobal {
broadcasts_only: self.broadcasts_only,
groups_only: self.groups_only,
users_only: self.users_only,
folder_id: self.folder_id,
q: self.query,
filter: self.filter,
min_date: self.min_date,
max_date: self.max_date,
offset_rate: self.offset_rate,
offset_peer: tl::enums::InputPeer::Empty,
offset_id: self.offset_id,
limit: self.limit,
};
let body = client.rpc_call_raw(&req).await?;
let mut cur = Cursor::from_slice(&body);
let msgs = match tl::enums::messages::Messages::deserialize(&mut cur)? {
tl::enums::messages::Messages::Messages(m) => m.messages,
tl::enums::messages::Messages::Slice(m) => m.messages,
tl::enums::messages::Messages::ChannelMessages(m) => m.messages,
tl::enums::messages::Messages::NotModified(_) => vec![],
};
Ok(msgs
.into_iter()
.map(update::IncomingMessage::from_raw)
.collect())
}
}