use crate::models::{ChatId, ChatMember, Message, Update};
use crate::{Bot, BotState};
pub trait FromUpdate<'r, T: Sync>
where
Self: Sized,
{
fn from_update(bot: &'r Bot, update: &'r Update, state: Option<&'r BotState<T>>) -> Option<Self>;
}
impl<'r, T: Sync> FromUpdate<'r, T> for &'r Bot {
fn from_update(bot: &'r Bot, _: &Update, _: Option<&BotState<T>>) -> Option<Self> {
Some(bot)
}
}
impl<'r, T: Sync> FromUpdate<'r, T> for &'r Update {
fn from_update(_: &Bot, update: &'r Update, _: Option<&BotState<T>>) -> Option<Self> {
Some(update)
}
}
impl<'r, T: Sync> FromUpdate<'r, T> for &'r BotState<T> {
fn from_update(_: &Bot, _: &Update, state: Option<&'r BotState<T>>) -> Option<Self> {
state
}
}
impl<'r, T: Sync> FromUpdate<'r, T> for &'r Message {
fn from_update(_: &Bot, u: &'r Update, _: Option<&BotState<T>>) -> Option<Self> {
match u {
Update::NewMessage(_, m) => Some(m),
Update::EditedMessage(_, m) => Some(m),
Update::NewChannelPost(_, m) => Some(m),
Update::EditedChannelPost(_, m) => Some(m),
Update::CallBackQuery(_, c) => c.message.as_ref(),
_ => None,
}
}
}
impl<'r, T: Sync> FromUpdate<'r, T> for ChatId {
fn from_update(_: &Bot, u: &'r Update, _: Option<&BotState<T>>) -> Option<Self> {
match u {
Update::NewMessage(_, Message { chat, .. }) => Some(chat.id.into()),
Update::EditedMessage(_, Message { chat, .. }) => Some(chat.id.into()),
Update::NewChannelPost(_, Message { chat, .. }) => Some(chat.id.into()),
Update::EditedChannelPost(_, Message { chat, .. }) => Some(chat.id.into()),
Update::CallBackQuery(_, c) => c.message.as_ref().map(|m| m.chat.id.into()),
Update::BotStatus(_, s) => {
if let ChatMember::Updated { chat, .. } = s {
Some(chat.id.into())
} else {
None
}
}
Update::MemberStatus(_, s) => {
if let ChatMember::Updated { chat, .. } = s {
Some(chat.id.into())
} else {
None
}
}
Update::ChatJoinRequest(_, r) => Some(r.chat.id.into()),
_ => None,
}
}
}