diff --git a/src/telegram/display.rs b/src/telegram/display.rs index d53170a..a301fe4 100644 --- a/src/telegram/display.rs +++ b/src/telegram/display.rs @@ -153,10 +153,10 @@ fn display_levelup(levelup: &String) -> String { } } -/// Render a [Deck] in [Telegram Bot HTML]. +/// Render a [Deck] in [Telegram Bot HTML], with an optional `name`. /// /// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style -pub fn display_deck(index: &CardIndex, deck: &Deck, code: String) -> String { +pub fn display_deck(index: &CardIndex, deck: &Deck, code: &str, name: &Option<&str>) -> String { // TODO: optimize this let cards = deck .contents @@ -182,5 +182,8 @@ pub fn display_deck(index: &CardIndex, deck: &Deck, code: String) -> String { }) .join("\n"); - format!("{}\n\n{}", &code, &cards) + match name { + Some(name) => format!("{}\n{}\n\n{}", &name, &code, &cards), + None => format!("{}\n\n{}", &code, &cards), + } } diff --git a/src/telegram/handler.rs b/src/telegram/handler.rs index c2fff99..7cc1f34 100644 --- a/src/telegram/handler.rs +++ b/src/telegram/handler.rs @@ -10,6 +10,8 @@ use teloxide::payloads::{AnswerInlineQuery, SendMessage}; use teloxide::prelude::*; use teloxide::requests::{JsonRequest, ResponseResult}; use teloxide::types::{ParseMode, Recipient}; +use lazy_static::lazy_static; +use regex::Regex; /// Handle inline queries by searching cards on the [CardSearchEngine]. pub fn inline_query_handler( @@ -33,17 +35,28 @@ pub fn inline_query_handler( }; } - if let Ok(deck) = Deck::from_code(&query.query.to_ascii_uppercase()) { - debug!("Parsed deck successfully!"); - break AnswerInlineQuery { - inline_query_id: query.id.clone(), - results: vec![deck_to_inlinequeryresult(&engine.cards, &deck)], - cache_time: None, - is_personal: Some(false), - next_offset: None, - switch_pm_text: None, - switch_pm_parameter: None, - }; + lazy_static! { + static ref DECK_RE: Regex = Regex::new(r#"^(?P[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]+)(?:\s+(?P.+?))?\s*$"#).unwrap(); + } + + if let Some(deck_captures) = DECK_RE.captures(&query.query) { + if let Some(deck_code) = deck_captures.name("code") { + if let Ok(deck) = Deck::from_code(&deck_code.as_str()) { + + debug!("Parsed deck successfully!"); + let name = deck_captures.name("name").map(|m| m.as_str()); + + break AnswerInlineQuery { + inline_query_id: query.id.clone(), + results: vec![deck_to_inlinequeryresult(&engine.cards, &deck, &name)], + cache_time: None, + is_personal: Some(false), + next_offset: None, + switch_pm_text: None, + switch_pm_parameter: None, + }; + } + } } debug!("Querying the card search engine..."); diff --git a/src/telegram/inline.rs b/src/telegram/inline.rs index 3b55fef..8eae007 100644 --- a/src/telegram/inline.rs +++ b/src/telegram/inline.rs @@ -43,17 +43,20 @@ pub fn card_to_inlinequeryresult( }) } -/// Convert a [Deck] into a [InlineQueryResult]. -pub fn deck_to_inlinequeryresult(index: &CardIndex, deck: &Deck) -> InlineQueryResult { +/// Convert a [Deck] with an optional name into a [InlineQueryResult]. +pub fn deck_to_inlinequeryresult(index: &CardIndex, deck: &Deck, name: &Option<&str>) -> InlineQueryResult { let code = deck .to_code(DeckCodeFormat::F1) .expect("serialized deck to deserialize properly"); InlineQueryResult::Article(InlineQueryResultArticle { id: format!("{:x}", md5::compute(&code)), - title: format!("Deck with {} cards", deck.contents.len()), + title: match &name { + Some(name) => format!(r#"Deck "{}" with {} cards"#, name, deck.contents.len()), + None => format!("Deck with {} cards", deck.contents.len()) + }, input_message_content: InputMessageContent::Text(InputMessageContentText { - message_text: display_deck(index, deck, code), + message_text: display_deck(index, deck, &code, &name), parse_mode: Some(ParseMode::Html), entities: None, disable_web_page_preview: Some(true),