Skip to main content

layer_client/
inline_iter.rs

1//! Paginated inline query iterator.
2//!
3//! Unlike the update stream which delivers live inline queries as they arrive,
4//! [`InlineQueryIter`] lets you replay/inspect queries stored in the update
5//! buffer.  It is backed by an [`tokio::sync::mpsc`] channel so callers can
6//! pull inline queries one at a time instead of blocking on `stream_updates`.
7
8use tokio::sync::mpsc;
9use crate::update::{InlineQuery, Update};
10use crate::Client;
11
12// ─── InlineQueryIter ─────────────────────────────────────────────────────────
13
14/// Async iterator over incoming inline queries.
15///
16/// Created by [`Client::iter_inline_queries`].  Each call to [`next`] blocks
17/// until the next inline query arrives or the client disconnects.
18///
19/// # Example
20/// ```rust,no_run
21/// # async fn f(client: layer_client::Client) {
22/// let mut iter = client.iter_inline_queries();
23/// while let Some(query) = iter.next().await {
24///     println!("Inline query from {}: {:?}", query.user_id, query.query());
25/// }
26/// # }
27/// ```
28pub struct InlineQueryIter {
29    rx: mpsc::UnboundedReceiver<InlineQuery>,
30}
31
32impl InlineQueryIter {
33    /// Wait for the next inline query.  Returns `None` when the stream ends.
34    pub async fn next(&mut self) -> Option<InlineQuery> {
35        self.rx.recv().await
36    }
37}
38
39// ─── Client extension ─────────────────────────────────────────────────────────
40
41impl Client {
42    /// Return an [`InlineQueryIter`] that yields every incoming inline query.
43    ///
44    /// Internally this spawns the same update loop as [`stream_updates`] but
45    /// filters for [`Update::InlineQuery`] events only.
46    ///
47    /// [`stream_updates`]: Client::stream_updates
48    pub fn iter_inline_queries(&self) -> InlineQueryIter {
49        let (tx, rx) = mpsc::unbounded_channel();
50        let client   = self.clone();
51
52        tokio::spawn(async move {
53            let mut stream = client.stream_updates();
54            loop {
55                match stream.next().await {
56                    Some(Update::InlineQuery(q)) => {
57                        if tx.send(q).is_err() { break; }
58                    }
59                    Some(_) => {} // ignore other updates
60                    None    => break,
61                }
62            }
63        });
64
65        InlineQueryIter { rx }
66    }
67}