1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use crate::types::{MessageEntity, User};

/// Converts an optional iterator to a flattened iterator.
pub(crate) fn flatten<I>(opt: Option<I>) -> impl Iterator<Item = I::Item>
where
    I: IntoIterator,
{
    struct Flat<I>(Option<I>);

    impl<I> Iterator for Flat<I>
    where
        I: Iterator,
    {
        type Item = I::Item;

        fn next(&mut self) -> Option<Self::Item> {
            self.0.as_mut()?.next()
        }

        fn size_hint(&self) -> (usize, Option<usize>) {
            match &self.0 {
                None => (0, Some(0)),
                Some(i) => i.size_hint(),
            }
        }
    }

    Flat(opt.map(<_>::into_iter))
}

pub(crate) fn mentioned_users_from_entities(
    entities: &[MessageEntity],
) -> impl Iterator<Item = &User> {
    use crate::types::MessageEntityKind::*;

    entities.iter().filter_map(|entity| match &entity.kind {
        TextMention { user } => Some(user),

        Mention
        | Hashtag
        | Cashtag
        | BotCommand
        | Url
        | Email
        | PhoneNumber
        | Bold
        | Italic
        | Underline
        | Strikethrough
        | Spoiler
        | Code
        | Pre { language: _ }
        | TextLink { url: _ }
        | CustomEmoji { custom_emoji_id: _ } => None,
    })
}