mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
delete filters
This commit is contained in:
parent
583d021be7
commit
4db07fc189
8 changed files with 0 additions and 945 deletions
|
@ -1,125 +0,0 @@
|
|||
use crate::{dispatching::Filter, types::Message};
|
||||
|
||||
/// Filter which find command in message text
|
||||
///
|
||||
/// *NB:* filter compare only text of message, not caption of media message
|
||||
///
|
||||
/// Examples:
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::CommandFilter;
|
||||
/// CommandFilter::new("start"); // filter will return true if text message starts with "/start"
|
||||
/// CommandFilter::with_prefix("!", "ban"); // filter will return true if text message starts with "!ban"
|
||||
/// ```
|
||||
pub struct CommandFilter {
|
||||
command: String,
|
||||
}
|
||||
|
||||
impl Filter<Message> for CommandFilter {
|
||||
fn test(&self, value: &Message) -> bool {
|
||||
match value.text() {
|
||||
Some(text) => text.starts_with(&self.command),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CommandFilter {
|
||||
pub fn new<T>(command: T) -> Self
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
Self {
|
||||
command: '/'.to_string() + &command.into(),
|
||||
}
|
||||
}
|
||||
pub fn with_prefix<T, U>(prefix: U, command: T) -> Self
|
||||
where
|
||||
T: Into<String>,
|
||||
U: Into<String>,
|
||||
{
|
||||
Self {
|
||||
command: prefix.into() + &command.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::types::{
|
||||
Chat, ChatKind, ForwardKind, MediaKind, MessageKind, Sender, User,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn commands_are_equal() {
|
||||
let filter = CommandFilter::new("command");
|
||||
let message = create_message_with_text("/command".to_string());
|
||||
assert!(filter.test(&message));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn commands_are_not_equal() {
|
||||
let filter = CommandFilter::new("command");
|
||||
let message =
|
||||
create_message_with_text("/not_equal_command".to_string());
|
||||
assert_eq!(filter.test(&message), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn command_have_args() {
|
||||
let filter = CommandFilter::new("command");
|
||||
let message =
|
||||
create_message_with_text("/command arg1 arg2".to_string());
|
||||
assert!(filter.test(&message));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn message_have_only_whitespace() {
|
||||
let filter = CommandFilter::new("command");
|
||||
let message = create_message_with_text(" ".to_string());
|
||||
assert_eq!(filter.test(&message), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn another_prefix() {
|
||||
let filter = CommandFilter::with_prefix("command", "!");
|
||||
let message = create_message_with_text("!command".to_string());
|
||||
assert!(filter.test(&message));
|
||||
}
|
||||
|
||||
fn create_message_with_text(text: String) -> Message {
|
||||
Message {
|
||||
id: 0,
|
||||
date: 0,
|
||||
chat: Chat {
|
||||
id: 0,
|
||||
kind: ChatKind::Private {
|
||||
type_: (),
|
||||
username: None,
|
||||
first_name: None,
|
||||
last_name: None,
|
||||
},
|
||||
photo: None,
|
||||
},
|
||||
kind: MessageKind::Common {
|
||||
from: Sender::User(User {
|
||||
id: 0,
|
||||
is_bot: false,
|
||||
first_name: "".to_string(),
|
||||
last_name: None,
|
||||
username: None,
|
||||
language_code: None,
|
||||
}),
|
||||
forward_kind: ForwardKind::Origin {
|
||||
reply_to_message: None,
|
||||
},
|
||||
edit_date: None,
|
||||
media_kind: MediaKind::Text {
|
||||
text,
|
||||
entities: vec![],
|
||||
},
|
||||
reply_markup: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,379 +0,0 @@
|
|||
/// Filter that determines that particular event
|
||||
/// is suitable for particular handler.
|
||||
pub trait Filter<T> {
|
||||
/// Passes (return true) if event is suitable (otherwise return false)
|
||||
fn test(&self, value: &T) -> bool;
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::Filter;
|
||||
///
|
||||
/// let closure = |i: &i32| -> bool { *i >= 42 };
|
||||
/// assert!(closure.test(&42));
|
||||
/// assert!(closure.test(&100));
|
||||
///
|
||||
/// assert_eq!(closure.test(&41), false);
|
||||
/// assert_eq!(closure.test(&0), false);
|
||||
/// ```
|
||||
impl<T, F: Fn(&T) -> bool> Filter<T> for F {
|
||||
fn test(&self, value: &T) -> bool {
|
||||
(self)(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::Filter;
|
||||
///
|
||||
/// assert!(true.test(&()));
|
||||
/// assert_eq!(false.test(&()), false);
|
||||
/// ```
|
||||
impl<T> Filter<T> for bool {
|
||||
fn test(&self, _: &T) -> bool {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
/// And filter.
|
||||
///
|
||||
/// Passes if both underlying filters pass.
|
||||
///
|
||||
/// **NOTE**: if one of filters don't pass
|
||||
/// it is **not** guaranteed that other will be executed.
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{And, Filter};
|
||||
///
|
||||
/// // Note: bool can be treated as `Filter` that always return self.
|
||||
/// assert_eq!(And::new(true, false).test(&()), false);
|
||||
/// assert_eq!(And::new(true, false).test(&()), false);
|
||||
/// assert!(And::new(true, true).test(&()));
|
||||
/// assert!(And::new(true, And::new(|_: &()| true, true)).test(&()));
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct And<A, B>(A, B);
|
||||
|
||||
impl<A, B> And<A, B> {
|
||||
pub fn new(a: A, b: B) -> Self {
|
||||
And(a, b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A, B> Filter<T> for And<A, B>
|
||||
where
|
||||
A: Filter<T>,
|
||||
B: Filter<T>,
|
||||
{
|
||||
fn test(&self, value: &T) -> bool {
|
||||
self.0.test(value) && self.1.test(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Alias for [`And::new`]
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{and, Filter};
|
||||
///
|
||||
/// assert!(and(true, true).test(&()));
|
||||
/// assert_eq!(and(true, false).test(&()), false);
|
||||
/// ```
|
||||
///
|
||||
/// [`And::new`]: crate::dispatching::filters::And::new
|
||||
pub fn and<A, B>(a: A, b: B) -> And<A, B> {
|
||||
And::new(a, b)
|
||||
}
|
||||
|
||||
/// Or filter.
|
||||
///
|
||||
/// Passes if at least one underlying filters passes.
|
||||
///
|
||||
/// **NOTE**: if one of filters passes
|
||||
/// it is **not** guaranteed that other will be executed.
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{Filter, Or};
|
||||
///
|
||||
/// // Note: bool can be treated as `Filter` that always return self.
|
||||
/// assert!(Or::new(true, false).test(&()));
|
||||
/// assert!(Or::new(false, true).test(&()));
|
||||
/// assert!(Or::new(false, Or::new(|_: &()| true, false)).test(&()));
|
||||
/// assert_eq!(Or::new(false, false).test(&()), false);
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Or<A, B>(A, B);
|
||||
|
||||
impl<A, B> Or<A, B> {
|
||||
pub fn new(a: A, b: B) -> Self {
|
||||
Or(a, b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A, B> Filter<T> for Or<A, B>
|
||||
where
|
||||
A: Filter<T>,
|
||||
B: Filter<T>,
|
||||
{
|
||||
fn test(&self, value: &T) -> bool {
|
||||
self.0.test(value) || self.1.test(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Alias for [`Or::new`]
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{or, Filter};
|
||||
///
|
||||
/// assert!(or(true, false).test(&()));
|
||||
/// assert_eq!(or(false, false).test(&()), false);
|
||||
/// ```
|
||||
///
|
||||
/// [`Or::new`]: crate::dispatching::filters::Or::new
|
||||
pub fn or<A, B>(a: A, b: B) -> Or<A, B> {
|
||||
Or::new(a, b)
|
||||
}
|
||||
|
||||
/// Not filter.
|
||||
///
|
||||
/// Passes if underlying filter don't pass.
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{Filter, Not};
|
||||
///
|
||||
/// // Note: bool can be treated as `Filter` that always return self.
|
||||
/// assert!(Not::new(false).test(&()));
|
||||
/// assert_eq!(Not::new(true).test(&()), false);
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Not<A>(A);
|
||||
|
||||
impl<A> Not<A> {
|
||||
pub fn new(a: A) -> Self {
|
||||
Not(a)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A> Filter<T> for Not<A>
|
||||
where
|
||||
A: Filter<T>,
|
||||
{
|
||||
fn test(&self, value: &T) -> bool {
|
||||
!self.0.test(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Alias for [`Not::new`]
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{not, Filter};
|
||||
///
|
||||
/// assert!(not(false).test(&()));
|
||||
/// assert_eq!(not(true).test(&()), false);
|
||||
/// ```
|
||||
///
|
||||
/// [`Not::new`]: crate::dispatching::filters::Not::new
|
||||
pub fn not<A>(a: A) -> Not<A> {
|
||||
Not::new(a)
|
||||
}
|
||||
|
||||
/// Return [filter] that passes if and only if all of the given filters passes.
|
||||
///
|
||||
/// **NOTE**: if one of filters don't pass
|
||||
/// it is **not** guaranteed that other will be executed.
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::{all, dispatching::filters::Filter};
|
||||
///
|
||||
/// assert!(all![true].test(&()));
|
||||
/// assert!(all![true, true].test(&()));
|
||||
/// assert!(all![true, true, true].test(&()));
|
||||
///
|
||||
/// assert_eq!(all![false].test(&()), false);
|
||||
/// assert_eq!(all![true, false].test(&()), false);
|
||||
/// assert_eq!(all![false, true].test(&()), false);
|
||||
/// assert_eq!(all![false, false].test(&()), false);
|
||||
/// ```
|
||||
///
|
||||
/// [filter]: crate::dispatching::filters::Filter
|
||||
#[macro_export]
|
||||
macro_rules! all {
|
||||
($one:expr) => { $one };
|
||||
($head:expr, $($tail:tt)+) => {
|
||||
$crate::dispatching::filters::And::new(
|
||||
$head,
|
||||
$crate::all!($($tail)+)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// Return [filter] that passes if any of the given filters passes.
|
||||
///
|
||||
/// **NOTE**: if one of filters passes
|
||||
/// it is **not** guaranteed that other will be executed.
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::{any, dispatching::filters::Filter};
|
||||
///
|
||||
/// assert!(any![true].test(&()));
|
||||
/// assert!(any![true, true].test(&()));
|
||||
/// assert!(any![false, true].test(&()));
|
||||
/// assert!(any![true, false, true].test(&()));
|
||||
///
|
||||
/// assert_eq!(any![false].test(&()), false);
|
||||
/// assert_eq!(any![false, false].test(&()), false);
|
||||
/// assert_eq!(any![false, false, false].test(&()), false);
|
||||
/// ```
|
||||
///
|
||||
/// [filter]: crate::dispatching::filters::Filter
|
||||
#[macro_export]
|
||||
macro_rules! any {
|
||||
($one:expr) => { $one };
|
||||
($head:expr, $($tail:tt)+) => {
|
||||
$crate::dispatching::filters::Or::new(
|
||||
$head,
|
||||
$crate::all!($($tail)+)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// Simple wrapper around `Filter` that adds `|` and `&` operators.
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{f, And, Filter, Or, F};
|
||||
///
|
||||
/// let flt1 = |i: &i32| -> bool { *i > 17 };
|
||||
/// let flt2 = |i: &i32| -> bool { *i < 42 };
|
||||
/// let flt3 = |i: &i32| -> bool { *i % 2 == 0 };
|
||||
///
|
||||
/// let and = f(flt1) & flt2;
|
||||
/// assert!(and.test(&19)); // both filters pass
|
||||
///
|
||||
/// assert_eq!(and.test(&50), false); // `flt2` doesn't pass
|
||||
/// assert_eq!(and.test(&16), false); // `flt1` doesn't pass
|
||||
///
|
||||
/// let or = f(flt1) | flt3;
|
||||
/// assert!(or.test(&19)); // `flt1` passes
|
||||
/// assert!(or.test(&16)); // `flt2` passes
|
||||
/// assert!(or.test(&20)); // both pass
|
||||
///
|
||||
/// assert_eq!(or.test(&17), false); // both don't pass
|
||||
///
|
||||
/// // Note: only first filter in chain should be wrapped in `f(...)`
|
||||
/// let complicated: F<Or<And<_, _>, _>> = f(flt1) & flt2 | flt3;
|
||||
/// assert!(complicated.test(&2)); // `flt3` passes
|
||||
/// assert!(complicated.test(&21)); // `flt1` and `flt2` pass
|
||||
///
|
||||
/// assert_eq!(complicated.test(&15), false); // `flt1` and `flt3` don't pass
|
||||
/// assert_eq!(complicated.test(&43), false); // `flt2` and `flt3` don't pass
|
||||
/// ```
|
||||
pub struct F<A>(A);
|
||||
|
||||
/// Constructor fn for [F]
|
||||
///
|
||||
/// [F]: crate::dispatching::filters::F;
|
||||
pub fn f<A>(a: A) -> F<A> {
|
||||
F(a)
|
||||
}
|
||||
|
||||
impl<T, A> Filter<T> for F<A>
|
||||
where
|
||||
A: Filter<T>,
|
||||
{
|
||||
fn test(&self, value: &T) -> bool {
|
||||
self.0.test(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B> std::ops::BitAnd<B> for F<A> {
|
||||
type Output = F<And<A, B>>;
|
||||
|
||||
fn bitand(self, other: B) -> Self::Output {
|
||||
f(and(self.0, other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, B> std::ops::BitOr<B> for F<A> {
|
||||
type Output = F<Or<A, B>>;
|
||||
|
||||
fn bitor(self, other: B) -> Self::Output {
|
||||
f(or(self.0, other))
|
||||
}
|
||||
}
|
||||
|
||||
/* workaround for `E0207` compiler error */
|
||||
/// Extensions for filters
|
||||
pub trait FilterExt<T> {
|
||||
/// Alias for [`Not::new`]
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{Filter, FilterExt};
|
||||
///
|
||||
/// let flt = |i: &i32| -> bool { *i > 0 };
|
||||
/// let flt = flt.not();
|
||||
/// assert!(flt.test(&-1));
|
||||
/// assert_eq!(flt.test(&1), false);
|
||||
/// ```
|
||||
///
|
||||
/// [`Not::new`]: crate::dispatching::filters::Not::new
|
||||
fn not(self) -> Not<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Not::new(self)
|
||||
}
|
||||
|
||||
/// Alias for [`And::new`]
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{Filter, FilterExt};
|
||||
///
|
||||
/// let flt = |i: &i32| -> bool { *i > 0 };
|
||||
/// let flt = flt.and(|i: &i32| *i < 42);
|
||||
///
|
||||
/// assert!(flt.test(&1));
|
||||
/// assert_eq!(flt.test(&-1), false);
|
||||
/// assert_eq!(flt.test(&43), false);
|
||||
/// ```
|
||||
///
|
||||
/// [`Not::new`]: crate::dispatching::filters::And::new
|
||||
fn and<B>(self, other: B) -> And<Self, B>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
And::new(self, other)
|
||||
}
|
||||
|
||||
/// Alias for [`Or::new`]
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// use teloxide::dispatching::filters::{Filter, FilterExt};
|
||||
///
|
||||
/// let flt = |i: &i32| -> bool { *i < 0 };
|
||||
/// let flt = flt.or(|i: &i32| *i > 42);
|
||||
///
|
||||
/// assert!(flt.test(&-1));
|
||||
/// assert!(flt.test(&43));
|
||||
/// assert_eq!(flt.test(&17), false);
|
||||
/// ```
|
||||
///
|
||||
/// [`Not::new`]: crate::dispatching::filters::Or::new
|
||||
fn or<B>(self, other: B) -> Or<Self, B>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Or::new(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
// All methods implemented via defaults
|
||||
impl<T, F> FilterExt<T> for F where F: Filter<T> {}
|
|
@ -1,100 +0,0 @@
|
|||
use crate::{dispatching::Filter, types::Message};
|
||||
|
||||
/// Filter which compare caption of media with another text.
|
||||
/// Returns true if the caption of media is equal to another text, otherwise
|
||||
/// false.
|
||||
///
|
||||
/// NOTE: filter compares only caption of media, does not compare text of
|
||||
/// message!
|
||||
///
|
||||
/// If you want to compare text of message use
|
||||
/// [MessageTextFilter]
|
||||
///
|
||||
/// If you want to compare text and caption use
|
||||
/// [MessageTextCaptionFilter]
|
||||
///
|
||||
/// [MessageTextFilter]: crate::dispatching::filters::MessageTextFilter
|
||||
/// [MessageTextCaptionFilter]:
|
||||
/// crate::dispatching::filters::MessageTextCaptionFilter
|
||||
pub struct MessageCaptionFilter {
|
||||
text: String,
|
||||
}
|
||||
|
||||
impl Filter<Message> for MessageCaptionFilter {
|
||||
fn test(&self, value: &Message) -> bool {
|
||||
match value.caption() {
|
||||
Some(caption) => self.text == caption,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageCaptionFilter {
|
||||
pub fn new<T>(text: T) -> Self
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
Self { text: text.into() }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::types::{
|
||||
Chat, ChatKind, ForwardKind, MediaKind, MessageKind, Sender, User,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn captions_are_equal() {
|
||||
let filter = MessageCaptionFilter::new("caption".to_string());
|
||||
let message = create_message_with_caption("caption".to_string());
|
||||
assert!(filter.test(&message));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn captions_are_not_equal() {
|
||||
let filter = MessageCaptionFilter::new("caption".to_string());
|
||||
let message =
|
||||
create_message_with_caption("not equal caption".to_string());
|
||||
assert_eq!(filter.test(&message), false);
|
||||
}
|
||||
|
||||
fn create_message_with_caption(caption: String) -> Message {
|
||||
Message {
|
||||
id: 0,
|
||||
date: 0,
|
||||
chat: Chat {
|
||||
id: 0,
|
||||
kind: ChatKind::Private {
|
||||
type_: (),
|
||||
username: None,
|
||||
first_name: None,
|
||||
last_name: None,
|
||||
},
|
||||
photo: None,
|
||||
},
|
||||
kind: MessageKind::Common {
|
||||
from: Sender::User(User {
|
||||
id: 0,
|
||||
is_bot: false,
|
||||
first_name: "".to_string(),
|
||||
last_name: None,
|
||||
username: None,
|
||||
language_code: None,
|
||||
}),
|
||||
forward_kind: ForwardKind::Origin {
|
||||
reply_to_message: None,
|
||||
},
|
||||
edit_date: None,
|
||||
media_kind: MediaKind::Photo {
|
||||
photo: vec![],
|
||||
caption: Some(caption),
|
||||
caption_entities: vec![],
|
||||
media_group_id: None,
|
||||
},
|
||||
reply_markup: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
use crate::{dispatching::Filter, types::Message};
|
||||
|
||||
/// Filter which compare message text with another text.
|
||||
/// Returns true if the message text is equal to another text, otherwise false.
|
||||
///
|
||||
/// NOTE: filter compares only text message, does not compare caption of media!
|
||||
///
|
||||
/// If you want to compare caption use
|
||||
/// [MessageCaptionFilter]
|
||||
///
|
||||
/// If you want to compare text and caption use
|
||||
/// [MessageTextCaptionFilter]
|
||||
///
|
||||
/// [MessageCaptionFilter]: crate::dispatching::filters::MessageCaptionFilter
|
||||
/// [MessageTextCaptionFilter]:
|
||||
/// crate::dispatching::filters::MessageTextCaptionFilter
|
||||
pub struct MessageTextFilter {
|
||||
text: String,
|
||||
}
|
||||
|
||||
impl Filter<Message> for MessageTextFilter {
|
||||
fn test(&self, value: &Message) -> bool {
|
||||
match value.text() {
|
||||
Some(text) => self.text == text,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageTextFilter {
|
||||
pub fn new<T>(text: T) -> Self
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
Self { text: text.into() }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::types::{
|
||||
Chat, ChatKind, ForwardKind, MediaKind, MessageKind, Sender, User,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn texts_are_equal() {
|
||||
let filter = MessageTextFilter::new("text");
|
||||
let message = create_message_with_text("text".to_string());
|
||||
assert!(filter.test(&message));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn texts_are_not_equal() {
|
||||
let filter = MessageTextFilter::new("text");
|
||||
let message = create_message_with_text("not equal text".to_string());
|
||||
assert_eq!(filter.test(&message), false);
|
||||
}
|
||||
|
||||
fn create_message_with_text(text: String) -> Message {
|
||||
Message {
|
||||
id: 0,
|
||||
date: 0,
|
||||
chat: Chat {
|
||||
id: 0,
|
||||
kind: ChatKind::Private {
|
||||
type_: (),
|
||||
username: None,
|
||||
first_name: None,
|
||||
last_name: None,
|
||||
},
|
||||
photo: None,
|
||||
},
|
||||
kind: MessageKind::Common {
|
||||
from: Sender::User(User {
|
||||
id: 0,
|
||||
is_bot: false,
|
||||
first_name: "".to_string(),
|
||||
last_name: None,
|
||||
username: None,
|
||||
language_code: None,
|
||||
}),
|
||||
forward_kind: ForwardKind::Origin {
|
||||
reply_to_message: None,
|
||||
},
|
||||
edit_date: None,
|
||||
media_kind: MediaKind::Text {
|
||||
text,
|
||||
entities: vec![],
|
||||
},
|
||||
reply_markup: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
use crate::{dispatching::Filter, types::Message};
|
||||
|
||||
/// Filter which compare message text or caption of media with another text.
|
||||
/// Returns true if the message text or caption of media is equal to another
|
||||
/// text, otherwise false.
|
||||
///
|
||||
/// NOTE: filter compares text of message or if it is not exists, compares
|
||||
/// caption of the message!
|
||||
///
|
||||
/// If you want to compare only caption use
|
||||
/// [MessageCaptionFilter]
|
||||
///
|
||||
/// If you want to compare only text use
|
||||
/// [MessageTextFilter]
|
||||
///
|
||||
/// [MessageCaptionFilter]: crate::dispatching::filters::MessageCaptionFilter
|
||||
/// [MessageTextFilter]: crate::dispatching::filters::MessageTextFilter
|
||||
pub struct MessageTextCaptionFilter {
|
||||
text: String,
|
||||
}
|
||||
|
||||
impl Filter<Message> for MessageTextCaptionFilter {
|
||||
fn test(&self, value: &Message) -> bool {
|
||||
match value.text() {
|
||||
Some(text) => self.text == text,
|
||||
None => match value.caption() {
|
||||
Some(caption) => self.text == caption,
|
||||
None => false,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageTextCaptionFilter {
|
||||
pub fn new<T>(text: T) -> Self
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
Self { text: text.into() }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::types::{
|
||||
Chat, ChatKind, ForwardKind, MediaKind, MessageKind, Sender, User,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn texts_are_equal() {
|
||||
let filter = MessageTextCaptionFilter::new("text");
|
||||
let message = create_message_with_text("text".to_string());
|
||||
assert!(filter.test(&message));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn texts_are_not_equal() {
|
||||
let filter = MessageTextCaptionFilter::new("text");
|
||||
let message = create_message_with_text("not equal text".to_string());
|
||||
assert_eq!(filter.test(&message), false);
|
||||
}
|
||||
|
||||
fn create_message_with_text(text: String) -> Message {
|
||||
Message {
|
||||
id: 0,
|
||||
date: 0,
|
||||
chat: Chat {
|
||||
id: 0,
|
||||
kind: ChatKind::Private {
|
||||
type_: (),
|
||||
username: None,
|
||||
first_name: None,
|
||||
last_name: None,
|
||||
},
|
||||
photo: None,
|
||||
},
|
||||
kind: MessageKind::Common {
|
||||
from: Sender::User(User {
|
||||
id: 0,
|
||||
is_bot: false,
|
||||
first_name: "".to_string(),
|
||||
last_name: None,
|
||||
username: None,
|
||||
language_code: None,
|
||||
}),
|
||||
forward_kind: ForwardKind::Origin {
|
||||
reply_to_message: None,
|
||||
},
|
||||
edit_date: None,
|
||||
media_kind: MediaKind::Text {
|
||||
text,
|
||||
entities: vec![],
|
||||
},
|
||||
reply_markup: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn captions_are_equal() {
|
||||
let filter = MessageTextCaptionFilter::new("caption".to_string());
|
||||
let message = create_message_with_caption("caption".to_string());
|
||||
assert!(filter.test(&message));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn captions_are_not_equal() {
|
||||
let filter = MessageTextCaptionFilter::new("caption".to_string());
|
||||
let message =
|
||||
create_message_with_caption("not equal caption".to_string());
|
||||
assert_eq!(filter.test(&message), false);
|
||||
}
|
||||
|
||||
fn create_message_with_caption(caption: String) -> Message {
|
||||
Message {
|
||||
id: 0,
|
||||
date: 0,
|
||||
chat: Chat {
|
||||
id: 0,
|
||||
kind: ChatKind::Private {
|
||||
type_: (),
|
||||
username: None,
|
||||
first_name: None,
|
||||
last_name: None,
|
||||
},
|
||||
photo: None,
|
||||
},
|
||||
kind: MessageKind::Common {
|
||||
from: Sender::User(User {
|
||||
id: 0,
|
||||
is_bot: false,
|
||||
first_name: "".to_string(),
|
||||
last_name: None,
|
||||
username: None,
|
||||
language_code: None,
|
||||
}),
|
||||
forward_kind: ForwardKind::Origin {
|
||||
reply_to_message: None,
|
||||
},
|
||||
edit_date: None,
|
||||
media_kind: MediaKind::Photo {
|
||||
photo: vec![],
|
||||
caption: Some(caption),
|
||||
caption_entities: vec![],
|
||||
media_group_id: None,
|
||||
},
|
||||
reply_markup: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
//! Filters of messages.
|
||||
|
||||
pub use main::*;
|
||||
|
||||
pub use command::*;
|
||||
pub use message_caption::*;
|
||||
pub use message_text::*;
|
||||
pub use message_text_caption::*;
|
||||
#[cfg(feature = "regex_filter")]
|
||||
pub use regex_filter::*;
|
||||
|
||||
mod main;
|
||||
|
||||
mod command;
|
||||
mod message_caption;
|
||||
mod message_text;
|
||||
mod message_text_caption;
|
||||
#[cfg(feature = "regex_filter")]
|
||||
mod regex_filter;
|
|
@ -1,73 +0,0 @@
|
|||
use crate::{dispatching::Filter, types::Message};
|
||||
use regex::Regex;
|
||||
|
||||
// TODO: docs
|
||||
pub struct RegexFilter {
|
||||
regexp: Regex,
|
||||
}
|
||||
|
||||
impl Filter<Message> for RegexFilter {
|
||||
fn test(&self, value: &Message) -> bool {
|
||||
match value.text() {
|
||||
Some(text) => self.regexp.is_match(text),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RegexFilter {
|
||||
pub fn new(regexp: Regex) -> Self {
|
||||
Self { regexp }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::types::{
|
||||
Chat, ChatKind, ForwardKind, MediaKind, MessageKind, Sender, User,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn match_true() {
|
||||
let filter = RegexFilter::new(Regex::new(r"\w+").unwrap());
|
||||
let message = create_message_with_text("text".to_string());
|
||||
assert!(filter.test(&message));
|
||||
}
|
||||
|
||||
fn create_message_with_text(text: String) -> Message {
|
||||
Message {
|
||||
id: 0,
|
||||
date: 0,
|
||||
chat: Chat {
|
||||
id: 0,
|
||||
kind: ChatKind::Private {
|
||||
type_: (),
|
||||
username: None,
|
||||
first_name: None,
|
||||
last_name: None,
|
||||
},
|
||||
photo: None,
|
||||
},
|
||||
kind: MessageKind::Common {
|
||||
from: Sender::User(User {
|
||||
id: 0,
|
||||
is_bot: false,
|
||||
first_name: "".to_string(),
|
||||
last_name: None,
|
||||
username: None,
|
||||
language_code: None,
|
||||
}),
|
||||
forward_kind: ForwardKind::Origin {
|
||||
reply_to_message: None,
|
||||
},
|
||||
edit_date: None,
|
||||
media_kind: MediaKind::Text {
|
||||
text,
|
||||
entities: vec![],
|
||||
},
|
||||
reply_markup: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
//mod dispatchers;
|
||||
pub mod error_handlers;
|
||||
pub mod filters;
|
||||
mod handler;
|
||||
pub mod updaters;
|
||||
|
||||
//pub use dispatchers::filter::FilterDispatcher;
|
||||
pub use error_handlers::ErrorHandler;
|
||||
pub use filters::Filter;
|
||||
pub use handler::Handler;
|
||||
pub use updaters::Updater;
|
||||
|
|
Loading…
Reference in a new issue