mirror of
https://github.com/Steffo99/patched-porobot.git
synced 2024-12-22 09:34:21 +00:00
Configure and run cargo fmt
This commit is contained in:
parent
f954588c34
commit
a2cc2cc4c0
29 changed files with 484 additions and 351 deletions
0
rustfmt.toml
Normal file
0
rustfmt.toml
Normal file
|
@ -77,7 +77,6 @@
|
|||
|
||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/Steffo99/patched-porobot/main/icon.png")]
|
||||
|
||||
|
||||
#[doc(hidden)]
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
//!
|
||||
//! [Data Dragon]: https://developer.riotgames.com/docs/lor#data-dragon
|
||||
|
||||
use crate::data::anybundle::outcomes::{LoadingError, LoadingResult};
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use crate::data::anybundle::outcomes::{LoadingError, LoadingResult};
|
||||
|
||||
/// A parsed `metadata.json` file from a Data Dragon Bundle.
|
||||
///
|
||||
|
@ -24,17 +24,15 @@ pub struct BundleMetadata {
|
|||
/// [Vec] of locales included in the bundle.
|
||||
///
|
||||
/// The specification defines that there can be multiple, but currently I've never seen more (or less) than one.
|
||||
pub locales: Vec<String>
|
||||
pub locales: Vec<String>,
|
||||
}
|
||||
|
||||
|
||||
impl BundleMetadata {
|
||||
/// Load a `metadata.json` file to create a [BundleMetadata] instance.
|
||||
pub fn load(path: &Path) -> LoadingResult<Self> {
|
||||
let file = File::open(path)
|
||||
.map_err(LoadingError::OpeningFile)?;
|
||||
let data = serde_json::de::from_reader::<File, Self>(file)
|
||||
.map_err(LoadingError::Deserializing)?;
|
||||
let file = File::open(path).map_err(LoadingError::OpeningFile)?;
|
||||
let data =
|
||||
serde_json::de::from_reader::<File, Self>(file).map_err(LoadingError::Deserializing)?;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
|
@ -46,7 +44,6 @@ impl BundleMetadata {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -54,13 +51,16 @@ mod tests {
|
|||
#[test]
|
||||
fn deserialize() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, BundleMetadata>(r#"
|
||||
serde_json::de::from_str::<'static, BundleMetadata>(
|
||||
r#"
|
||||
{
|
||||
"locales": [
|
||||
"en_us"
|
||||
]
|
||||
}
|
||||
"#).unwrap(),
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
BundleMetadata {
|
||||
locales: vec!["en_us".to_string()]
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
//!
|
||||
//! [Data Dragon]: https://developer.riotgames.com/docs/lor#data-dragon
|
||||
|
||||
|
||||
/// An error that occoured while loading a Data Dragon Bundle.
|
||||
#[derive(Debug)]
|
||||
pub enum LoadingError {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
//! Module defining structs representing data contained in `globals.json` files.
|
||||
|
||||
use super::keyword::{LocalizedCardKeywordIndex, LocalizedCardKeywordVec};
|
||||
use super::rarity::{LocalizedCardRarityIndex, LocalizedCardRarityVec};
|
||||
use super::region::{LocalizedCardRegionIndex, LocalizedCardRegionVec};
|
||||
use super::set::{LocalizedCardSetIndex, LocalizedCardSetVec};
|
||||
use super::speed::{LocalizedSpellSpeedIndex, LocalizedSpellSpeedVec};
|
||||
use super::vocabterm::{LocalizedVocabTermIndex, LocalizedVocabTermVec};
|
||||
use crate::data::anybundle::outcomes::{LoadingError, LoadingResult};
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use crate::data::anybundle::outcomes::{LoadingError, LoadingResult};
|
||||
use super::vocabterm::{LocalizedVocabTermVec, LocalizedVocabTermIndex};
|
||||
use super::keyword::{LocalizedCardKeywordVec, LocalizedCardKeywordIndex};
|
||||
use super::region::{LocalizedCardRegionVec, LocalizedCardRegionIndex};
|
||||
use super::speed::{LocalizedSpellSpeedVec, LocalizedSpellSpeedIndex};
|
||||
use super::rarity::{LocalizedCardRarityVec, LocalizedCardRarityIndex};
|
||||
use super::set::{LocalizedCardSetVec, LocalizedCardSetIndex};
|
||||
|
||||
/// A parsed `globals.json` file from a [Data Dragon] [Core Bundle].
|
||||
///
|
||||
|
@ -68,19 +68,16 @@ pub struct LocalizedGlobalsIndexes {
|
|||
pub sets: LocalizedCardSetIndex,
|
||||
}
|
||||
|
||||
|
||||
impl LocalizedGlobalsVecs {
|
||||
/// Load a `globals.json` file to create a [LocalizedGlobalsVecs] instance.
|
||||
pub fn load(path: &Path) -> LoadingResult<Self> {
|
||||
let file = File::open(path)
|
||||
.map_err(LoadingError::OpeningFile)?;
|
||||
let data = serde_json::de::from_reader::<File, Self>(file)
|
||||
.map_err(LoadingError::Deserializing)?;
|
||||
let file = File::open(path).map_err(LoadingError::OpeningFile)?;
|
||||
let data =
|
||||
serde_json::de::from_reader::<File, Self>(file).map_err(LoadingError::Deserializing)?;
|
||||
Ok(data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl From<LocalizedGlobalsVecs> for LocalizedGlobalsIndexes {
|
||||
fn from(o: LocalizedGlobalsVecs) -> Self {
|
||||
Self {
|
||||
|
@ -130,7 +127,6 @@ impl From<LocalizedGlobalsVecs> for LocalizedGlobalsIndexes {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::LocalizedGlobalsVecs;
|
||||
|
@ -149,7 +145,8 @@ mod tests {
|
|||
#[test]
|
||||
fn deserialize() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, LocalizedGlobalsVecs>(r#"
|
||||
serde_json::de::from_str::<'static, LocalizedGlobalsVecs>(
|
||||
r#"
|
||||
{
|
||||
"vocabTerms": [
|
||||
{
|
||||
|
@ -193,50 +190,10 @@ mod tests {
|
|||
}
|
||||
]
|
||||
}
|
||||
"#).unwrap(),
|
||||
LocalizedGlobalsVecs {
|
||||
vocab_terms: vec![
|
||||
LocalizedVocabTerm {
|
||||
vocabterm: "Allegiance".to_string(),
|
||||
name: "Allegiance".to_string(),
|
||||
description: "When you summon this, it gets its allegiance bonus if the top card of your deck matches its region.".to_string(),
|
||||
}
|
||||
],
|
||||
keywords: vec![
|
||||
LocalizedCardKeyword {
|
||||
keyword: CardKeyword::SpellOverwhelm,
|
||||
name: "Overwhelm".to_string(),
|
||||
description: "Inflicts damage beyond what would kill the target(s) to the enemy Nexus.".to_string(),
|
||||
}
|
||||
],
|
||||
regions: vec![
|
||||
LocalizedCardRegion {
|
||||
region: CardRegion::Noxus,
|
||||
name: "Noxus".to_string(),
|
||||
abbreviation: "NX".to_string(),
|
||||
icon_png: "http://dd.b.pvp.net/3_11_0/core/en_us/img/regions/icon-noxus.png".to_string(),
|
||||
}
|
||||
],
|
||||
spell_speeds: vec![
|
||||
LocalizedSpellSpeed {
|
||||
spell_speed: SpellSpeed::Slow,
|
||||
name: "Slow".to_string(),
|
||||
}
|
||||
],
|
||||
rarities: vec![
|
||||
LocalizedCardRarity {
|
||||
rarity: CardRarity::Common,
|
||||
name: "COMMON".to_string(),
|
||||
}
|
||||
],
|
||||
sets: vec![
|
||||
LocalizedCardSet {
|
||||
set: CardSet::CallOfTheMountain,
|
||||
name: "Call of the Mountain".to_string(),
|
||||
icon_png: "http://dd.b.pvp.net/3_11_0/core/en_us/img/sets/set3_crispmip.png".to_string(),
|
||||
}
|
||||
]
|
||||
}
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
LocalizedGlobalsVecs { vocab_terms: vec![LocalizedVocabTerm { vocabterm: "Allegiance".to_string(), name: "Allegiance".to_string(), description: "When you summon this, it gets its allegiance bonus if the top card of your deck matches its region.".to_string() }], keywords: vec![LocalizedCardKeyword { keyword: CardKeyword::SpellOverwhelm, name: "Overwhelm".to_string(), description: "Inflicts damage beyond what would kill the target(s) to the enemy Nexus.".to_string() }], regions: vec![LocalizedCardRegion { region: CardRegion::Noxus, name: "Noxus".to_string(), abbreviation: "NX".to_string(), icon_png: "http://dd.b.pvp.net/3_11_0/core/en_us/img/regions/icon-noxus.png".to_string() }], spell_speeds: vec![LocalizedSpellSpeed { spell_speed: SpellSpeed::Slow, name: "Slow".to_string() }], rarities: vec![LocalizedCardRarity { rarity: CardRarity::Common, name: "COMMON".to_string() }], sets: vec![LocalizedCardSet { set: CardSet::CallOfTheMountain, name: "Call of the Mountain".to_string(), icon_png: "http://dd.b.pvp.net/3_11_0/core/en_us/img/sets/set3_crispmip.png".to_string() }] }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[rustfmt::skip]
|
||||
fn deserialize() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, LocalizedCardKeyword>(r#"
|
||||
|
|
|
@ -3,18 +3,17 @@
|
|||
//! [Data Dragon]: https://developer.riotgames.com/docs/lor#data-dragon
|
||||
//! [Core Bundle]: https://developer.riotgames.com/docs/lor#data-dragon_core-bundles
|
||||
|
||||
use std::path::Path;
|
||||
use super::anybundle::metadata::BundleMetadata;
|
||||
use crate::data::anybundle::outcomes::{LoadingError, LoadingResult};
|
||||
use std::path::Path;
|
||||
|
||||
pub mod globals;
|
||||
pub mod vocabterm;
|
||||
pub mod keyword;
|
||||
pub mod region;
|
||||
pub mod speed;
|
||||
pub mod rarity;
|
||||
pub mod region;
|
||||
pub mod set;
|
||||
|
||||
pub mod speed;
|
||||
pub mod vocabterm;
|
||||
|
||||
/// A parsed [Data Dragon] [Core Bundle].
|
||||
///
|
||||
|
@ -32,23 +31,19 @@ pub struct CoreBundle {
|
|||
pub globals: globals::LocalizedGlobalsVecs,
|
||||
}
|
||||
|
||||
|
||||
impl CoreBundle {
|
||||
/// Load a Core Bundle directory to create a [CoreBundle] instance.
|
||||
pub fn load(bundle_path: &Path) -> LoadingResult<Self> {
|
||||
let metadata = BundleMetadata::load(
|
||||
&bundle_path
|
||||
.join("metadata.json")
|
||||
)?;
|
||||
let metadata = BundleMetadata::load(&bundle_path.join("metadata.json"))?;
|
||||
|
||||
let name = bundle_path.file_name()
|
||||
let name = bundle_path
|
||||
.file_name()
|
||||
.ok_or(LoadingError::GettingBundleName)?
|
||||
.to_str()
|
||||
.ok_or(LoadingError::ConvertingBundleName)?
|
||||
.to_string();
|
||||
|
||||
let locale = metadata.locale()
|
||||
.ok_or(LoadingError::GettingLocale)?;
|
||||
let locale = metadata.locale().ok_or(LoadingError::GettingLocale)?;
|
||||
|
||||
let globals_path = &bundle_path
|
||||
.join(&locale)
|
||||
|
@ -57,6 +52,10 @@ impl CoreBundle {
|
|||
|
||||
let globals = globals::LocalizedGlobalsVecs::load(globals_path)?;
|
||||
|
||||
Ok(CoreBundle {name, metadata, globals})
|
||||
Ok(CoreBundle {
|
||||
name,
|
||||
metadata,
|
||||
globals,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[rustfmt::skip]
|
||||
fn deserialize() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, LocalizedCardRarity>(r#"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Module defining structs representing localized card regions.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use crate::data::setbundle::region::CardRegion;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// A Legends of Runeterra [CardRegion], and its associated localization.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
|
||||
|
@ -28,7 +28,6 @@ pub type LocalizedCardRegionVec = Vec<LocalizedCardRegion>;
|
|||
/// An index of [LocalizedCardRegion]s, with [LocalizedCardRegion::region]s as keys.
|
||||
pub type LocalizedCardRegionIndex = HashMap<CardRegion, LocalizedCardRegion>;
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -36,19 +35,22 @@ mod tests {
|
|||
#[test]
|
||||
fn deserialize() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, LocalizedCardRegion>(r#"
|
||||
serde_json::de::from_str::<'static, LocalizedCardRegion>(
|
||||
r#"
|
||||
{
|
||||
"abbreviation": "NX",
|
||||
"iconAbsolutePath": "http://dd.b.pvp.net/3_11_0/core/en_us/img/regions/icon-noxus.png",
|
||||
"name": "Noxus",
|
||||
"nameRef": "Noxus"
|
||||
}
|
||||
"#).unwrap(),
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
LocalizedCardRegion {
|
||||
region: CardRegion::Noxus,
|
||||
name: "Noxus".to_string(),
|
||||
abbreviation: "NX".to_string(),
|
||||
icon_png: "http://dd.b.pvp.net/3_11_0/core/en_us/img/regions/icon-noxus.png".to_string(),
|
||||
icon_png: "http://dd.b.pvp.net/3_11_0/core/en_us/img/regions/icon-noxus.png".to_string()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[rustfmt::skip]
|
||||
fn deserialize() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, LocalizedCardSet>(r#"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Module defining structs representing localized spell speeds.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use crate::data::setbundle::speed::SpellSpeed;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// A Legends of Runeterra [SpellSpeed], and its associated localization.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
|
||||
|
@ -19,7 +19,6 @@ pub type LocalizedSpellSpeedVec = Vec<LocalizedSpellSpeed>;
|
|||
/// An index of [LocalizedSpellSpeed]s, with [LocalizedSpellSpeed::spell_speed]s as keys.
|
||||
pub type LocalizedSpellSpeedIndex = HashMap<SpellSpeed, LocalizedSpellSpeed>;
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -27,15 +26,18 @@ mod tests {
|
|||
#[test]
|
||||
fn deserialize() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, LocalizedSpellSpeed>(r#"
|
||||
serde_json::de::from_str::<'static, LocalizedSpellSpeed>(
|
||||
r#"
|
||||
{
|
||||
"name": "Slow",
|
||||
"nameRef": "Slow"
|
||||
}
|
||||
"#).unwrap(),
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
LocalizedSpellSpeed {
|
||||
spell_speed: SpellSpeed::Slow,
|
||||
name: "Slow".to_string(),
|
||||
name: "Slow".to_string()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[rustfmt::skip]
|
||||
fn deserialize() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, LocalizedVocabTerm>(r#"
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//!
|
||||
//! [Data Dragon]: https://developer.riotgames.com/docs/lor#data-dragon
|
||||
|
||||
pub mod anybundle;
|
||||
pub mod corebundle;
|
||||
pub mod setbundle;
|
||||
pub mod anybundle;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//! Module defining [CardArt].
|
||||
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
|
||||
|
@ -30,7 +29,6 @@ pub struct CardArt {
|
|||
pub full_png: String,
|
||||
}
|
||||
|
||||
|
||||
impl CardArt {
|
||||
/// URL to the `.jpg` image of the `en_us` locale of the rendered card, via `poro.steffo.eu`.
|
||||
///
|
||||
|
@ -46,10 +44,16 @@ impl CardArt {
|
|||
lazy_static! {
|
||||
static ref GET_JPG: Regex = Regex::new(
|
||||
r#"https?://dd[.]b[.]pvp[.]net/[^/]+/(?P<bundle>[^/]+)/(?P<locale>[^/]+)/img/cards/(?P<code>.+)[.]png$"#
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
GET_JPG.replace_all(&self.card_png, "https://poro.steffo.eu/$bundle-$locale/$locale/img/cards/$code.jpg").to_string()
|
||||
GET_JPG
|
||||
.replace_all(
|
||||
&self.card_png,
|
||||
"https://poro.steffo.eu/$bundle-$locale/$locale/img/cards/$code.jpg",
|
||||
)
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// URL to the `.jpg` image of the `en_us` locale of the full card art, via `poro.steffo.eu`.
|
||||
|
@ -66,37 +70,44 @@ impl CardArt {
|
|||
lazy_static! {
|
||||
static ref GET_JPG: Regex = Regex::new(
|
||||
r#"https?://dd[.]b[.]pvp[.]net/[^/]+/(?P<bundle>[^/]+)/(?P<locale>[^/]+)/img/cards/(?P<code>.+)[.]png$"#
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
GET_JPG.replace_all(&self.full_png, "https://poro.steffo.eu/$bundle-$locale/$locale/img/cards/$code.jpg").to_string()
|
||||
GET_JPG
|
||||
.replace_all(
|
||||
&self.full_png,
|
||||
"https://poro.steffo.eu/$bundle-$locale/$locale/img/cards/$code.jpg",
|
||||
)
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::CardArt;
|
||||
|
||||
#[test]
|
||||
fn deserialize() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, CardArt>(r#"{"gameAbsolutePath": "https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001.png", "fullAbsolutePath": "https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001-full.png"}"#).unwrap(),
|
||||
CardArt {
|
||||
card_png: String::from("https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001.png"),
|
||||
full_png: String::from("https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001-full.png"),
|
||||
}
|
||||
);
|
||||
assert_eq!(serde_json::de::from_str::<'static, CardArt>(r#"{"gameAbsolutePath": "https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001.png", "fullAbsolutePath": "https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001-full.png"}"#).unwrap(), CardArt { card_png: String::from("https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001.png"), full_png: String::from("https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001-full.png") });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn png_to_jpg() {
|
||||
let art = CardArt {
|
||||
card_png: String::from("https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001.png"),
|
||||
full_png: String::from("https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001-full.png"),
|
||||
full_png: String::from(
|
||||
"https://dd.b.pvp.net/latest/set1/en_us/img/cards/01DE001-full.png",
|
||||
),
|
||||
};
|
||||
|
||||
assert_eq!(art.card_jpg(), "https://poro.steffo.eu/set1-en_us/en_us/img/cards/01DE001.jpg");
|
||||
assert_eq!(art.full_jpg(), "https://poro.steffo.eu/set1-en_us/en_us/img/cards/01DE001-full.jpg");
|
||||
assert_eq!(
|
||||
art.card_jpg(),
|
||||
"https://poro.steffo.eu/set1-en_us/en_us/img/cards/01DE001.jpg"
|
||||
);
|
||||
assert_eq!(
|
||||
art.full_jpg(),
|
||||
"https://poro.steffo.eu/set1-en_us/en_us/img/cards/01DE001-full.jpg"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,6 +169,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[rustfmt::skip]
|
||||
fn deserialize_card() {
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, Card>(r#"
|
||||
|
|
|
@ -342,12 +342,14 @@ impl CardKeyword {
|
|||
/// Returns [Option::None] if no matching [LocalizedCardKeyword] was found, for example for [CardKeyword::Unsupported] keywords.
|
||||
///
|
||||
/// Equivalent to calling [LocalizedCardKeywordIndex::get].
|
||||
pub fn localized<'hm>(&self, hm: &'hm LocalizedCardKeywordIndex) -> Option<&'hm LocalizedCardKeyword> {
|
||||
pub fn localized<'hm>(
|
||||
&self,
|
||||
hm: &'hm LocalizedCardKeywordIndex,
|
||||
) -> Option<&'hm LocalizedCardKeyword> {
|
||||
hm.get(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::CardKeyword;
|
||||
|
@ -356,79 +358,202 @@ mod tests {
|
|||
( $id:ident, $src:literal, $res:expr ) => {
|
||||
#[test]
|
||||
fn $id() {
|
||||
assert_eq!(serde_json::de::from_str::<'static, CardKeyword>($src).unwrap(), $res);
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, CardKeyword>($src).unwrap(),
|
||||
$res
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test_deserialization!(deserialize_spelloverwhelm, r#""SpellOverwhelm""#, CardKeyword::SpellOverwhelm);
|
||||
test_deserialization!(
|
||||
deserialize_spelloverwhelm,
|
||||
r#""SpellOverwhelm""#,
|
||||
CardKeyword::SpellOverwhelm
|
||||
);
|
||||
test_deserialization!(deserialize_burst, r#""Burst""#, CardKeyword::Burst);
|
||||
test_deserialization!(deserialize_countdown, r#""Countdown""#, CardKeyword::Countdown);
|
||||
test_deserialization!(deserialize_onplay, r#""PlaySkillMark""#, CardKeyword::OnPlay);
|
||||
test_deserialization!(deserialize_landmark, r#""LandmarkVisualOnly""#, CardKeyword::Landmark);
|
||||
test_deserialization!(
|
||||
deserialize_countdown,
|
||||
r#""Countdown""#,
|
||||
CardKeyword::Countdown
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_onplay,
|
||||
r#""PlaySkillMark""#,
|
||||
CardKeyword::OnPlay
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_landmark,
|
||||
r#""LandmarkVisualOnly""#,
|
||||
CardKeyword::Landmark
|
||||
);
|
||||
test_deserialization!(deserialize_shurima, r#""Shurima""#, CardKeyword::Shurima);
|
||||
test_deserialization!(deserialize_attach, r#""Attach""#, CardKeyword::Attach);
|
||||
test_deserialization!(deserialize_noxus, r#""Noxus""#, CardKeyword::Noxus);
|
||||
test_deserialization!(deserialize_fleeting, r#""Fleeting""#, CardKeyword::Fleeting);
|
||||
test_deserialization!(deserialize_clobbernoemptyslotrequirement, r#""ClobberNoEmptySlotRequirement""#, CardKeyword::ClobberNoEmptySlotRequirement);
|
||||
test_deserialization!(
|
||||
deserialize_clobbernoemptyslotrequirement,
|
||||
r#""ClobberNoEmptySlotRequirement""#,
|
||||
CardKeyword::ClobberNoEmptySlotRequirement
|
||||
);
|
||||
test_deserialization!(deserialize_nab, r#""Nab""#, CardKeyword::Nab);
|
||||
test_deserialization!(deserialize_focus, r#""Focus""#, CardKeyword::Focus);
|
||||
test_deserialization!(deserialize_enlightened, r#""Enlightened""#, CardKeyword::Enlightened);
|
||||
test_deserialization!(
|
||||
deserialize_enlightened,
|
||||
r#""Enlightened""#,
|
||||
CardKeyword::Enlightened
|
||||
);
|
||||
test_deserialization!(deserialize_invoke, r#""Invoke""#, CardKeyword::Invoke);
|
||||
test_deserialization!(deserialize_boon, r#""Boon""#, CardKeyword::Boon);
|
||||
test_deserialization!(deserialize_trap, r#""Autoplay""#, CardKeyword::Trap);
|
||||
test_deserialization!(deserialize_drain, r#""Drain""#, CardKeyword::Drain);
|
||||
test_deserialization!(deserialize_lastbreath, r#""LastBreath""#, CardKeyword::LastBreath);
|
||||
test_deserialization!(
|
||||
deserialize_lastbreath,
|
||||
r#""LastBreath""#,
|
||||
CardKeyword::LastBreath
|
||||
);
|
||||
test_deserialization!(deserialize_demacia, r#""Demacia""#, CardKeyword::Demacia);
|
||||
test_deserialization!(deserialize_bandlecity, r#""BandleCity""#, CardKeyword::BandleCity);
|
||||
test_deserialization!(
|
||||
deserialize_bandlecity,
|
||||
r#""BandleCity""#,
|
||||
CardKeyword::BandleCity
|
||||
);
|
||||
test_deserialization!(deserialize_fast, r#""Fast""#, CardKeyword::Fast);
|
||||
test_deserialization!(deserialize_bilgewater, r#""Bilgewater""#, CardKeyword::Bilgewater);
|
||||
test_deserialization!(deserialize_runeterra, r#""Runeterra""#, CardKeyword::Runeterra);
|
||||
test_deserialization!(
|
||||
deserialize_bilgewater,
|
||||
r#""Bilgewater""#,
|
||||
CardKeyword::Bilgewater
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_runeterra,
|
||||
r#""Runeterra""#,
|
||||
CardKeyword::Runeterra
|
||||
);
|
||||
test_deserialization!(deserialize_recall, r#""Recall""#, CardKeyword::Recall);
|
||||
test_deserialization!(deserialize_weakest, r#""Weakest""#, CardKeyword::Weakest);
|
||||
test_deserialization!(deserialize_support, r#""Support""#, CardKeyword::Support);
|
||||
test_deserialization!(deserialize_slow, r#""Slow""#, CardKeyword::Slow);
|
||||
test_deserialization!(deserialize_obliterate, r#""Obliterate""#, CardKeyword::Obliterate);
|
||||
test_deserialization!(
|
||||
deserialize_obliterate,
|
||||
r#""Obliterate""#,
|
||||
CardKeyword::Obliterate
|
||||
);
|
||||
test_deserialization!(deserialize_imbue, r#""Imbue""#, CardKeyword::Imbue);
|
||||
test_deserialization!(deserialize_targon, r#""MtTargon""#, CardKeyword::Targon);
|
||||
test_deserialization!(deserialize_shadowisles, r#""ShadowIsles""#, CardKeyword::ShadowIsles);
|
||||
test_deserialization!(deserialize_auravisualfakekeyword, r#""AuraVisualFakeKeyword""#, CardKeyword::AuraVisualFakeKeyword);
|
||||
test_deserialization!(
|
||||
deserialize_shadowisles,
|
||||
r#""ShadowIsles""#,
|
||||
CardKeyword::ShadowIsles
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_auravisualfakekeyword,
|
||||
r#""AuraVisualFakeKeyword""#,
|
||||
CardKeyword::AuraVisualFakeKeyword
|
||||
);
|
||||
test_deserialization!(deserialize_ionia, r#""Ionia""#, CardKeyword::Ionia);
|
||||
test_deserialization!(deserialize_nightfall, r#""Nightfall""#, CardKeyword::Nightfall);
|
||||
test_deserialization!(deserialize_piltoverzaun, r#""PiltoverZaun""#, CardKeyword::PiltoverZaun);
|
||||
test_deserialization!(
|
||||
deserialize_nightfall,
|
||||
r#""Nightfall""#,
|
||||
CardKeyword::Nightfall
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_piltoverzaun,
|
||||
r#""PiltoverZaun""#,
|
||||
CardKeyword::PiltoverZaun
|
||||
);
|
||||
test_deserialization!(deserialize_attune, r#""Attune""#, CardKeyword::Attune);
|
||||
test_deserialization!(deserialize_daybreak, r#""Daybreak""#, CardKeyword::Daybreak);
|
||||
test_deserialization!(deserialize_silenceindividualkeyword, r#""SilenceIndividualKeyword""#, CardKeyword::SilenceIndividualKeyword);
|
||||
test_deserialization!(
|
||||
deserialize_silenceindividualkeyword,
|
||||
r#""SilenceIndividualKeyword""#,
|
||||
CardKeyword::SilenceIndividualKeyword
|
||||
);
|
||||
test_deserialization!(deserialize_skill, r#""Skill""#, CardKeyword::Skill);
|
||||
test_deserialization!(deserialize_plunder, r#""Plunder""#, CardKeyword::Plunder);
|
||||
test_deserialization!(deserialize_doubleattack, r#""DoubleAttack""#, CardKeyword::DoubleAttack);
|
||||
test_deserialization!(deserialize_vulnerable, r#""Vulnerable""#, CardKeyword::Vulnerable);
|
||||
test_deserialization!(
|
||||
deserialize_doubleattack,
|
||||
r#""DoubleAttack""#,
|
||||
CardKeyword::DoubleAttack
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_vulnerable,
|
||||
r#""Vulnerable""#,
|
||||
CardKeyword::Vulnerable
|
||||
);
|
||||
test_deserialization!(deserialize_elusive, r#""Elusive""#, CardKeyword::Elusive);
|
||||
test_deserialization!(deserialize_stun, r#""Stun""#, CardKeyword::Stun);
|
||||
test_deserialization!(deserialize_fated, r#""Fated""#, CardKeyword::Fated);
|
||||
test_deserialization!(deserialize_blockelusive, r#""BlockElusive""#, CardKeyword::BlockElusive);
|
||||
test_deserialization!(
|
||||
deserialize_blockelusive,
|
||||
r#""BlockElusive""#,
|
||||
CardKeyword::BlockElusive
|
||||
);
|
||||
test_deserialization!(deserialize_fury, r#""Fury""#, CardKeyword::Fury);
|
||||
test_deserialization!(deserialize_barrier, r#""Barrier""#, CardKeyword::Barrier);
|
||||
test_deserialization!(deserialize_immobile, r#""Immobile""#, CardKeyword::Immobile);
|
||||
test_deserialization!(deserialize_hallowed, r#""Hallowed""#, CardKeyword::Hallowed);
|
||||
test_deserialization!(deserialize_evolve, r#""Evolve""#, CardKeyword::Evolve);
|
||||
test_deserialization!(deserialize_frostbite, r#""Frostbite""#, CardKeyword::Frostbite);
|
||||
test_deserialization!(deserialize_overwhelm, r#""Overwhelm""#, CardKeyword::Overwhelm);
|
||||
test_deserialization!(deserialize_quickattack, r#""QuickStrike""#, CardKeyword::QuickAttack);
|
||||
test_deserialization!(
|
||||
deserialize_frostbite,
|
||||
r#""Frostbite""#,
|
||||
CardKeyword::Frostbite
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_overwhelm,
|
||||
r#""Overwhelm""#,
|
||||
CardKeyword::Overwhelm
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_quickattack,
|
||||
r#""QuickStrike""#,
|
||||
CardKeyword::QuickAttack
|
||||
);
|
||||
test_deserialization!(deserialize_tough, r#""Tough""#, CardKeyword::Tough);
|
||||
test_deserialization!(deserialize_regeneration, r#""Regeneration""#, CardKeyword::Regeneration);
|
||||
test_deserialization!(
|
||||
deserialize_regeneration,
|
||||
r#""Regeneration""#,
|
||||
CardKeyword::Regeneration
|
||||
);
|
||||
test_deserialization!(deserialize_silenced, r#""Silenced""#, CardKeyword::Silenced);
|
||||
test_deserialization!(deserialize_spellshield, r#""SpellShield""#, CardKeyword::SpellShield);
|
||||
test_deserialization!(deserialize_lifesteal, r#""Lifesteal""#, CardKeyword::Lifesteal);
|
||||
test_deserialization!(
|
||||
deserialize_spellshield,
|
||||
r#""SpellShield""#,
|
||||
CardKeyword::SpellShield
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_lifesteal,
|
||||
r#""Lifesteal""#,
|
||||
CardKeyword::Lifesteal
|
||||
);
|
||||
test_deserialization!(deserialize_augment, r#""Augment""#, CardKeyword::Augment);
|
||||
test_deserialization!(deserialize_impact, r#""Impact""#, CardKeyword::Impact);
|
||||
test_deserialization!(deserialize_scout, r#""Scout""#, CardKeyword::Scout);
|
||||
test_deserialization!(deserialize_ephemeral, r#""Ephemeral""#, CardKeyword::Ephemeral);
|
||||
test_deserialization!(
|
||||
deserialize_ephemeral,
|
||||
r#""Ephemeral""#,
|
||||
CardKeyword::Ephemeral
|
||||
);
|
||||
test_deserialization!(deserialize_lurk, r#""Lurker""#, CardKeyword::Lurk);
|
||||
test_deserialization!(deserialize_formidable, r#""Formidable""#, CardKeyword::Formidable);
|
||||
test_deserialization!(deserialize_challenger, r#""Challenger""#, CardKeyword::Challenger);
|
||||
test_deserialization!(
|
||||
deserialize_formidable,
|
||||
r#""Formidable""#,
|
||||
CardKeyword::Formidable
|
||||
);
|
||||
test_deserialization!(
|
||||
deserialize_challenger,
|
||||
r#""Challenger""#,
|
||||
CardKeyword::Challenger
|
||||
);
|
||||
test_deserialization!(deserialize_fearsome, r#""Fearsome""#, CardKeyword::Fearsome);
|
||||
test_deserialization!(deserialize_cantblock, r#""CantBlock""#, CardKeyword::CantBlock);
|
||||
test_deserialization!(
|
||||
deserialize_cantblock,
|
||||
r#""CantBlock""#,
|
||||
CardKeyword::CantBlock
|
||||
);
|
||||
test_deserialization!(deserialize_deep, r#""Deep""#, CardKeyword::Deep);
|
||||
test_deserialization!(deserialize_unsupported, r#""Xyzzy""#, CardKeyword::Unsupported);
|
||||
test_deserialization!(
|
||||
deserialize_unsupported,
|
||||
r#""Xyzzy""#,
|
||||
CardKeyword::Unsupported
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,22 +3,21 @@
|
|||
//! [Data Dragon]: https://developer.riotgames.com/docs/lor#data-dragon
|
||||
//! [Set Bundle]: https://developer.riotgames.com/docs/lor#data-dragon_set-bundles
|
||||
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use super::anybundle::metadata::BundleMetadata;
|
||||
use crate::data::anybundle::outcomes::{LoadingError, LoadingResult};
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
|
||||
pub mod card;
|
||||
pub mod art;
|
||||
pub mod r#type;
|
||||
pub mod card;
|
||||
pub mod keyword;
|
||||
pub mod rarity;
|
||||
pub mod region;
|
||||
pub mod set;
|
||||
pub mod speed;
|
||||
pub mod keyword;
|
||||
pub mod subtype;
|
||||
pub mod supertype;
|
||||
|
||||
pub mod r#type;
|
||||
|
||||
/// A parsed [Data Dragon] [Set Bundle].
|
||||
///
|
||||
|
@ -35,41 +34,38 @@ pub struct SetBundle {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
|
||||
impl SetBundle {
|
||||
/// Load a Set Bundle directory to create a [SetBundle] instance.
|
||||
pub fn load(bundle_path: &Path) -> LoadingResult<Self> {
|
||||
let metadata = BundleMetadata::load(
|
||||
&bundle_path
|
||||
.join("metadata.json")
|
||||
)?;
|
||||
let metadata = BundleMetadata::load(&bundle_path.join("metadata.json"))?;
|
||||
|
||||
let locale = metadata.locale()
|
||||
.ok_or(LoadingError::GettingLocale)?;
|
||||
let locale = metadata.locale().ok_or(LoadingError::GettingLocale)?;
|
||||
|
||||
let name = bundle_path.file_name()
|
||||
let name = bundle_path
|
||||
.file_name()
|
||||
.ok_or(LoadingError::GettingBundleName)?;
|
||||
|
||||
let data_path = {
|
||||
let mut json_filename = name.to_os_string();
|
||||
json_filename.push(".json");
|
||||
|
||||
&bundle_path
|
||||
.join(&locale)
|
||||
.join("data")
|
||||
.join(&json_filename)
|
||||
&bundle_path.join(&locale).join("data").join(&json_filename)
|
||||
};
|
||||
|
||||
let name = name.to_str()
|
||||
let name = name
|
||||
.to_str()
|
||||
.ok_or(LoadingError::ConvertingBundleName)?
|
||||
.to_string();
|
||||
|
||||
let cards = File::open(data_path)
|
||||
.map_err(LoadingError::OpeningFile)?;
|
||||
let cards = File::open(data_path).map_err(LoadingError::OpeningFile)?;
|
||||
|
||||
let cards = serde_json::de::from_reader::<File, Vec<card::Card>>(cards)
|
||||
.map_err(LoadingError::Deserializing)?;
|
||||
|
||||
Ok(SetBundle {metadata, cards, name})
|
||||
Ok(SetBundle {
|
||||
metadata,
|
||||
cards,
|
||||
name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,14 @@ impl CardRarity {
|
|||
/// Returns [Option::None] if no matching [LocalizedCardRarity] was found, for example rarities missing from the index.
|
||||
///
|
||||
/// Equivalent to calling [LocalizedCardRarityIndex::get].
|
||||
pub fn localized<'hm>(&self, hm: &'hm LocalizedCardRarityIndex) -> Option<&'hm LocalizedCardRarity> {
|
||||
pub fn localized<'hm>(
|
||||
&self,
|
||||
hm: &'hm LocalizedCardRarityIndex,
|
||||
) -> Option<&'hm LocalizedCardRarity> {
|
||||
hm.get(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::CardRarity;
|
||||
|
@ -41,9 +43,12 @@ mod tests {
|
|||
( $id:ident, $src:literal, $res:expr ) => {
|
||||
#[test]
|
||||
fn $id() {
|
||||
assert_eq!(serde_json::de::from_str::<'static, CardRarity>($src).unwrap(), $res);
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, CardRarity>($src).unwrap(),
|
||||
$res
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test_deserialization!(deserialize_none, r#""None""#, CardRarity::None);
|
||||
|
|
|
@ -55,6 +55,7 @@ impl CardRegion {
|
|||
|
||||
|
||||
#[cfg(test)]
|
||||
#[rustfmt::skip]
|
||||
mod tests {
|
||||
use super::CardRegion;
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ impl CardSet {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::CardSet;
|
||||
|
@ -61,9 +60,12 @@ mod tests {
|
|||
( $id:ident, $src:literal, $res:expr ) => {
|
||||
#[test]
|
||||
fn $id() {
|
||||
assert_eq!(serde_json::de::from_str::<'static, CardSet>($src).unwrap(), $res);
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, CardSet>($src).unwrap(),
|
||||
$res
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test_deserialization!(deserialize_set1, r#""Set1""#, CardSet::Foundations);
|
||||
|
|
|
@ -22,12 +22,14 @@ impl SpellSpeed {
|
|||
/// Returns [Option::None] if no matching [LocalizedSpellSpeed] was found, for example spell speeds missing from the index.
|
||||
///
|
||||
/// Equivalent to calling [LocalizedSpellSpeedIndex::get].
|
||||
pub fn localized<'hm>(&self, hm: &'hm LocalizedSpellSpeedIndex) -> Option<&'hm LocalizedSpellSpeed> {
|
||||
pub fn localized<'hm>(
|
||||
&self,
|
||||
hm: &'hm LocalizedSpellSpeedIndex,
|
||||
) -> Option<&'hm LocalizedSpellSpeed> {
|
||||
hm.get(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::SpellSpeed;
|
||||
|
@ -36,9 +38,12 @@ mod tests {
|
|||
( $id:ident, $src:literal, $res:expr ) => {
|
||||
#[test]
|
||||
fn $id() {
|
||||
assert_eq!(serde_json::de::from_str::<'static, SpellSpeed>($src).unwrap(), $res);
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, SpellSpeed>($src).unwrap(),
|
||||
$res
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test_deserialization!(deserialize_none, r#""""#, SpellSpeed::None);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//! Module defining [CardType].
|
||||
|
||||
|
||||
/// A possible [Card](super::card::Card) type.
|
||||
///
|
||||
/// Since more types might be added in the future, as it happened with landmarks, this enum is [non_exaustive](https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute).
|
||||
|
@ -31,7 +30,6 @@ pub enum CardType {
|
|||
Unsupported,
|
||||
}
|
||||
|
||||
|
||||
impl From<&CardType> for String {
|
||||
fn from(r#type: &CardType) -> Self {
|
||||
match r#type {
|
||||
|
@ -45,7 +43,6 @@ impl From<&CardType> for String {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::CardType;
|
||||
|
@ -54,9 +51,12 @@ mod tests {
|
|||
( $id:ident, $src:literal, $res:expr ) => {
|
||||
#[test]
|
||||
fn $id() {
|
||||
assert_eq!(serde_json::de::from_str::<'static, CardType>($src).unwrap(), $res);
|
||||
assert_eq!(
|
||||
serde_json::de::from_str::<'static, CardType>($src).unwrap(),
|
||||
$res
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test_deserialization!(deserialize_spell, r#""Spell""#, CardType::Spell);
|
||||
|
@ -64,4 +64,4 @@ mod tests {
|
|||
test_deserialization!(deserialize_ability, r#""Ability""#, CardType::Ability);
|
||||
test_deserialization!(deserialize_landmark, r#""Landmark""#, CardType::Landmark);
|
||||
test_deserialization!(deserialize_fallback, r#""Xyzzy""#, CardType::Unsupported);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
//! Module providing utilities to be used in the `patched_porobot_matrix` executable target.
|
||||
//!
|
||||
//! While adding new features to this module, remember that binaries [can only access the public API of the crate](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#binaries), as they considered a separate crate from the rest of the project.
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
//! Module defining a search engine to find [Card]s.
|
||||
|
||||
use tantivy::{Document, Index, IndexReader, IndexWriter};
|
||||
use crate::data::corebundle::globals::LocalizedGlobalsIndexes;
|
||||
use crate::data::setbundle::card::{Card, CardIndex};
|
||||
use itertools::Itertools;
|
||||
use tantivy::collector::TopDocs;
|
||||
use tantivy::query::{QueryParser, QueryParserError};
|
||||
use tantivy::schema::{Field, NumericOptions, Schema, TextOptions};
|
||||
use tantivy::tokenizer::TextAnalyzer;
|
||||
use itertools::Itertools;
|
||||
use crate::data::corebundle::globals::LocalizedGlobalsIndexes;
|
||||
use crate::data::setbundle::card::{Card, CardIndex};
|
||||
|
||||
use tantivy::{Document, Index, IndexReader, IndexWriter};
|
||||
|
||||
/// The search engine.
|
||||
///
|
||||
|
@ -29,10 +28,9 @@ pub struct CardSearchEngine {
|
|||
pub globals: LocalizedGlobalsIndexes,
|
||||
|
||||
/// Cards searchable in the search engine.
|
||||
pub cards: CardIndex
|
||||
pub cards: CardIndex,
|
||||
}
|
||||
|
||||
|
||||
impl CardSearchEngine {
|
||||
/// Create the [tantivy::tokenizer::TextAnalyzer] for card text.
|
||||
///
|
||||
|
@ -40,8 +38,7 @@ impl CardSearchEngine {
|
|||
fn tokenizer() -> TextAnalyzer {
|
||||
use tantivy::tokenizer::*;
|
||||
|
||||
TextAnalyzer::from(SimpleTokenizer)
|
||||
.filter(LowerCaser)
|
||||
TextAnalyzer::from(SimpleTokenizer).filter(LowerCaser)
|
||||
}
|
||||
|
||||
/// Create the [tantivy::schema::TextOptions] for card codes.
|
||||
|
@ -54,9 +51,10 @@ impl CardSearchEngine {
|
|||
use tantivy::schema::*;
|
||||
|
||||
TextOptions::default()
|
||||
.set_indexing_options(TextFieldIndexing::default()
|
||||
.set_tokenizer("card")
|
||||
.set_index_option(IndexRecordOption::Basic)
|
||||
.set_indexing_options(
|
||||
TextFieldIndexing::default()
|
||||
.set_tokenizer("card")
|
||||
.set_index_option(IndexRecordOption::Basic),
|
||||
)
|
||||
.set_stored()
|
||||
.set_fast()
|
||||
|
@ -70,11 +68,11 @@ impl CardSearchEngine {
|
|||
fn options_keyword() -> TextOptions {
|
||||
use tantivy::schema::*;
|
||||
|
||||
TextOptions::default()
|
||||
.set_indexing_options(TextFieldIndexing::default()
|
||||
TextOptions::default().set_indexing_options(
|
||||
TextFieldIndexing::default()
|
||||
.set_tokenizer("card")
|
||||
.set_index_option(IndexRecordOption::Basic)
|
||||
)
|
||||
.set_index_option(IndexRecordOption::Basic),
|
||||
)
|
||||
}
|
||||
|
||||
/// Create the [tantivy::schema::TextOptions] for card text fields.
|
||||
|
@ -85,11 +83,11 @@ impl CardSearchEngine {
|
|||
fn options_text() -> TextOptions {
|
||||
use tantivy::schema::*;
|
||||
|
||||
TextOptions::default()
|
||||
.set_indexing_options(TextFieldIndexing::default()
|
||||
TextOptions::default().set_indexing_options(
|
||||
TextFieldIndexing::default()
|
||||
.set_tokenizer("card")
|
||||
.set_index_option(IndexRecordOption::WithFreqsAndPositions)
|
||||
)
|
||||
.set_index_option(IndexRecordOption::WithFreqsAndPositions),
|
||||
)
|
||||
}
|
||||
|
||||
/// Create the [tantivy::schema::NumericOptions] for card numeric fields.
|
||||
|
@ -99,8 +97,7 @@ impl CardSearchEngine {
|
|||
fn options_number() -> NumericOptions {
|
||||
use tantivy::schema::*;
|
||||
|
||||
NumericOptions::default()
|
||||
.set_indexed()
|
||||
NumericOptions::default().set_indexed()
|
||||
}
|
||||
|
||||
/// Create the [Schema] for the search engine.
|
||||
|
@ -163,32 +160,66 @@ impl CardSearchEngine {
|
|||
/// Create a [CardSchemaFields] object from the given schema.
|
||||
fn schema_fields(schema: &Schema) -> CardSchemaFields {
|
||||
CardSchemaFields {
|
||||
code: schema.get_field("code").expect("schema to have a 'code' field"),
|
||||
name: schema.get_field("name").expect("schema to have a 'name' field"),
|
||||
r#type: schema.get_field("type").expect("schema to have a 'type' field"),
|
||||
set: schema.get_field("set").expect("schema to have a 'set' field"),
|
||||
rarity: schema.get_field("rarity").expect("schema to have a 'rarity' field"),
|
||||
collectible: schema.get_field("collectible").expect("schema to have a 'collectible' field"),
|
||||
regions: schema.get_field("regions").expect("schema to have a 'regions' field"),
|
||||
attack: schema.get_field("attack").expect("schema to have a 'attack' field"),
|
||||
cost: schema.get_field("cost").expect("schema to have a 'cost' field"),
|
||||
health: schema.get_field("health").expect("schema to have a 'health' field"),
|
||||
spellspeed: schema.get_field("spellspeed").expect("schema to have a 'spellspeed' field"),
|
||||
keywords: schema.get_field("keywords").expect("schema to have a 'keywords' field"),
|
||||
description: schema.get_field("description").expect("schema to have a 'description' field"),
|
||||
levelup: schema.get_field("levelup").expect("schema to have a 'levelup' field"),
|
||||
flavor: schema.get_field("flavor").expect("schema to have a 'flavor' field"),
|
||||
artist: schema.get_field("artist").expect("schema to have a 'artist' field"),
|
||||
subtypes: schema.get_field("subtypes").expect("schema to have a 'subtypes' field"),
|
||||
supertype: schema.get_field("supertype").expect("schema to have a 'supertype' field"),
|
||||
code: schema
|
||||
.get_field("code")
|
||||
.expect("schema to have a 'code' field"),
|
||||
name: schema
|
||||
.get_field("name")
|
||||
.expect("schema to have a 'name' field"),
|
||||
r#type: schema
|
||||
.get_field("type")
|
||||
.expect("schema to have a 'type' field"),
|
||||
set: schema
|
||||
.get_field("set")
|
||||
.expect("schema to have a 'set' field"),
|
||||
rarity: schema
|
||||
.get_field("rarity")
|
||||
.expect("schema to have a 'rarity' field"),
|
||||
collectible: schema
|
||||
.get_field("collectible")
|
||||
.expect("schema to have a 'collectible' field"),
|
||||
regions: schema
|
||||
.get_field("regions")
|
||||
.expect("schema to have a 'regions' field"),
|
||||
attack: schema
|
||||
.get_field("attack")
|
||||
.expect("schema to have a 'attack' field"),
|
||||
cost: schema
|
||||
.get_field("cost")
|
||||
.expect("schema to have a 'cost' field"),
|
||||
health: schema
|
||||
.get_field("health")
|
||||
.expect("schema to have a 'health' field"),
|
||||
spellspeed: schema
|
||||
.get_field("spellspeed")
|
||||
.expect("schema to have a 'spellspeed' field"),
|
||||
keywords: schema
|
||||
.get_field("keywords")
|
||||
.expect("schema to have a 'keywords' field"),
|
||||
description: schema
|
||||
.get_field("description")
|
||||
.expect("schema to have a 'description' field"),
|
||||
levelup: schema
|
||||
.get_field("levelup")
|
||||
.expect("schema to have a 'levelup' field"),
|
||||
flavor: schema
|
||||
.get_field("flavor")
|
||||
.expect("schema to have a 'flavor' field"),
|
||||
artist: schema
|
||||
.get_field("artist")
|
||||
.expect("schema to have a 'artist' field"),
|
||||
subtypes: schema
|
||||
.get_field("subtypes")
|
||||
.expect("schema to have a 'subtypes' field"),
|
||||
supertype: schema
|
||||
.get_field("supertype")
|
||||
.expect("schema to have a 'supertype' field"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Build [in RAM](Index::create_in_ram) the [Index] of the search engine.
|
||||
fn index() -> Index {
|
||||
Index::create_in_ram(
|
||||
Self::schema()
|
||||
)
|
||||
Index::create_in_ram(Self::schema())
|
||||
}
|
||||
|
||||
/// Build a [IndexWriter] with the optimal configuration for the search engine.
|
||||
|
@ -210,7 +241,11 @@ impl CardSearchEngine {
|
|||
}
|
||||
|
||||
/// Create a [Document] from a [Card].
|
||||
fn document(fields: &CardSchemaFields, globals: &LocalizedGlobalsIndexes, card: Card) -> Document {
|
||||
fn document(
|
||||
fields: &CardSchemaFields,
|
||||
globals: &LocalizedGlobalsIndexes,
|
||||
card: Card,
|
||||
) -> Document {
|
||||
use tantivy::doc;
|
||||
|
||||
doc!(
|
||||
|
@ -268,7 +303,7 @@ impl CardSearchEngine {
|
|||
fields.artist,
|
||||
fields.subtypes,
|
||||
fields.supertype,
|
||||
]
|
||||
],
|
||||
);
|
||||
parser.set_conjunction_by_default();
|
||||
parser.set_field_boost(fields.code, 3.0);
|
||||
|
@ -288,16 +323,24 @@ impl CardSearchEngine {
|
|||
let mut writer = Self::writer(&index);
|
||||
for card in cards.values() {
|
||||
let document = Self::document(&fields, &globals, card.clone());
|
||||
writer.add_document(document)
|
||||
writer
|
||||
.add_document(document)
|
||||
.expect("IndexWriter threads to not panic or die before adding a document");
|
||||
};
|
||||
writer.commit()
|
||||
}
|
||||
writer
|
||||
.commit()
|
||||
.expect("IndexWriter threads to not panic or die before commit");
|
||||
|
||||
let parser = Self::parser(&index, fields);
|
||||
let reader = Self::reader(&index);
|
||||
|
||||
Self {index, reader, parser, globals, cards}
|
||||
Self {
|
||||
index,
|
||||
reader,
|
||||
parser,
|
||||
globals,
|
||||
cards,
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform a query on the search engine.
|
||||
|
@ -306,13 +349,18 @@ impl CardSearchEngine {
|
|||
|
||||
let query = self.parser.parse_query(input)?;
|
||||
|
||||
let search = searcher.search(&*query, &TopDocs::with_limit(top))
|
||||
let search = searcher
|
||||
.search(&*query, &TopDocs::with_limit(top))
|
||||
.expect("Searcher::search to never fail");
|
||||
|
||||
let f_code = self.index.schema().get_field("code")
|
||||
let f_code = self
|
||||
.index
|
||||
.schema()
|
||||
.get_field("code")
|
||||
.expect("schema to have a 'code' field");
|
||||
|
||||
let results = search.iter()
|
||||
let results = search
|
||||
.iter()
|
||||
.filter_map(|(_score, address)| searcher.doc(address.to_owned()).ok())
|
||||
.filter_map(|doc| doc.get_first(f_code).cloned())
|
||||
.filter_map(|field| field.as_text().map(String::from))
|
||||
|
@ -323,7 +371,6 @@ impl CardSearchEngine {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Struct containing all retrieved [CardSearchEngine] [Field]s.
|
||||
///
|
||||
/// This makes it easier to pass them around without having to re-fetch them every time they are used.
|
||||
|
|
|
@ -2,45 +2,35 @@
|
|||
//!
|
||||
//! [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
|
||||
use itertools::Itertools;
|
||||
use teloxide::utils::html::escape;
|
||||
use crate::data::setbundle::card::Card;
|
||||
use crate::data::setbundle::r#type::CardType;
|
||||
use crate::data::corebundle::globals::LocalizedGlobalsIndexes;
|
||||
use crate::data::corebundle::keyword::LocalizedCardKeywordIndex;
|
||||
use crate::data::corebundle::region::LocalizedCardRegionIndex;
|
||||
use crate::data::corebundle::set::LocalizedCardSetIndex;
|
||||
use crate::data::setbundle::card::Card;
|
||||
use crate::data::setbundle::keyword::CardKeyword;
|
||||
use crate::data::setbundle::r#type::CardType;
|
||||
use crate::data::setbundle::region::CardRegion;
|
||||
use crate::data::setbundle::set::CardSet;
|
||||
use crate::data::setbundle::subtype::CardSubtype;
|
||||
use crate::data::setbundle::supertype::CardSupertype;
|
||||
|
||||
use itertools::Itertools;
|
||||
use teloxide::utils::html::escape;
|
||||
|
||||
/// Render a [Card] in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
pub fn display_card(globals: &LocalizedGlobalsIndexes, card: &Card) -> String {
|
||||
let title = format!(
|
||||
"<b><u>{}</u></b>\n",
|
||||
escape(&card.name),
|
||||
);
|
||||
let title = format!("<b><u>{}</u></b>\n", escape(&card.name),);
|
||||
|
||||
let stats = match &card.r#type {
|
||||
CardType::Spell => format!(
|
||||
"{} mana\n\n",
|
||||
escape(&card.cost.to_string()),
|
||||
),
|
||||
CardType::Spell => format!("{} mana\n\n", escape(&card.cost.to_string()),),
|
||||
CardType::Unit => format!(
|
||||
"{} mana {}|{}\n\n",
|
||||
escape(&card.cost.to_string()),
|
||||
escape(&card.attack.to_string()),
|
||||
escape(&card.health.to_string()),
|
||||
),
|
||||
CardType::Landmark => format!(
|
||||
"{} mana\n\n",
|
||||
&card.cost
|
||||
),
|
||||
CardType::Landmark => format!("{} mana\n\n", &card.cost),
|
||||
_ => "".to_string(),
|
||||
};
|
||||
|
||||
|
@ -55,60 +45,50 @@ pub fn display_card(globals: &LocalizedGlobalsIndexes, card: &Card) -> String {
|
|||
let description = display_description(&card.localized_description_text);
|
||||
let levelup = display_levelup(&card.localized_levelup_text);
|
||||
|
||||
let flavor = format!(
|
||||
"<i>{}</i>\n",
|
||||
escape(&card.localized_flavor_text)
|
||||
);
|
||||
let flavor = format!("<i>{}</i>\n", escape(&card.localized_flavor_text));
|
||||
|
||||
let artist = format!(
|
||||
r#"<a href="{}">Illustration</a> by {}"#,
|
||||
&card.main_art().expect("Card to have at least one illustration").full_png,
|
||||
&card
|
||||
.main_art()
|
||||
.expect("Card to have at least one illustration")
|
||||
.full_png,
|
||||
escape(&card.artist_name)
|
||||
);
|
||||
|
||||
format!(
|
||||
"{}{}{}{}{}{}-----\n{}{}",
|
||||
&title,
|
||||
&breadcrumbs,
|
||||
&keywords,
|
||||
&stats,
|
||||
&description,
|
||||
&levelup,
|
||||
&flavor,
|
||||
&artist,
|
||||
&title, &breadcrumbs, &keywords, &stats, &description, &levelup, &flavor, &artist,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/// Render a [CardSet] in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_set(set: &CardSet, hm: &LocalizedCardSetIndex) -> String {
|
||||
format!(
|
||||
"<i>{}</i>",
|
||||
set
|
||||
.localized(hm)
|
||||
set.localized(hm)
|
||||
.map(|o| format!("<i>{}</i>", escape(&o.name)))
|
||||
.unwrap_or_else(|| "Unknown".to_string())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/// Render a slice of [CardRegion]s in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_regions(regions: &[CardRegion], hm: &LocalizedCardRegionIndex) -> String {
|
||||
regions
|
||||
.iter()
|
||||
.map(|region| region
|
||||
.localized(hm)
|
||||
.map(|o| format!("<i>{}</i>", escape(&o.name)))
|
||||
.unwrap_or_else(|| "Unknown".to_string())
|
||||
)
|
||||
.map(|region| {
|
||||
region
|
||||
.localized(hm)
|
||||
.map(|o| format!("<i>{}</i>", escape(&o.name)))
|
||||
.unwrap_or_else(|| "Unknown".to_string())
|
||||
})
|
||||
.join(", ")
|
||||
}
|
||||
|
||||
|
||||
/// Render the [CardType], the [CardSupertype] and the [CardSubtype]s in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
|
@ -116,32 +96,24 @@ fn display_types(r#type: &CardType, supertype: &CardSupertype, subtypes: &[CardS
|
|||
let mut result = String::new();
|
||||
|
||||
if supertype != "" {
|
||||
result.push_str(&*format!(
|
||||
"<i>{}</i> › ",
|
||||
escape(&supertype),
|
||||
));
|
||||
result.push_str(&*format!("<i>{}</i> › ", escape(&supertype),));
|
||||
};
|
||||
|
||||
result.push_str(&*format!(
|
||||
"<i>{}</i>",
|
||||
escape(&*String::from(r#type)),
|
||||
));
|
||||
result.push_str(&*format!("<i>{}</i>", escape(&*String::from(r#type)),));
|
||||
|
||||
if subtypes.len() > 0 {
|
||||
result.push_str(
|
||||
&*format!(
|
||||
" › {}",
|
||||
subtypes.iter()
|
||||
.map(|subtype| format!("<i>{}</i>", escape(&subtype)))
|
||||
.join(", ")
|
||||
)
|
||||
)
|
||||
result.push_str(&*format!(
|
||||
" › {}",
|
||||
subtypes
|
||||
.iter()
|
||||
.map(|subtype| format!("<i>{}</i>", escape(&subtype)))
|
||||
.join(", ")
|
||||
))
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
/// Render a slice of [CardKeyword]s in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
|
@ -153,35 +125,29 @@ fn display_keywords(keywords: &[CardKeyword], hm: &LocalizedCardKeywordIndex) ->
|
|||
.map(|keyword| keyword
|
||||
.localized(hm)
|
||||
.map(|o| format!("[<b>{}</b>]", escape(&o.name)))
|
||||
.unwrap_or_else(|| "Unknown".to_string())
|
||||
)
|
||||
.unwrap_or_else(|| "Unknown".to_string()))
|
||||
.join(" ")
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Render a [Card::localized_description_text] in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_description(description: &String) -> String {
|
||||
if description == "" {
|
||||
"".to_string()
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
format!("{}\n\n", escape(&description))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Render a [Card::localized_levelup_text] in [Telegram Bot HTML].
|
||||
///
|
||||
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
|
||||
fn display_levelup(levelup: &String) -> String {
|
||||
if levelup == "" {
|
||||
"".to_string()
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
format!("<u>Level up</u>: {}\n\n", escape(&levelup))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
//! Module providing handlers for @patchedporobot on Telegram.
|
||||
|
||||
use crate::search::cardsearch::CardSearchEngine;
|
||||
use crate::telegram::inline::card_to_inlinequeryresult;
|
||||
use itertools::Itertools;
|
||||
use log::*;
|
||||
use teloxide::dispatching::DpHandlerDescription;
|
||||
use teloxide::payloads::{AnswerInlineQuery, SendMessage};
|
||||
use teloxide::requests::{JsonRequest, ResponseResult};
|
||||
use teloxide::prelude::*;
|
||||
use teloxide::requests::{JsonRequest, ResponseResult};
|
||||
use teloxide::types::{ParseMode, Recipient};
|
||||
use crate::search::cardsearch::CardSearchEngine;
|
||||
use crate::telegram::inline::card_to_inlinequeryresult;
|
||||
|
||||
|
||||
/// Handle inline queries by searching cards on the [CardSearchEngine].
|
||||
pub fn inline_query_handler(engine: CardSearchEngine) -> Handler<'static, DependencyMap, ResponseResult<()>, DpHandlerDescription> {
|
||||
pub fn inline_query_handler(
|
||||
engine: CardSearchEngine,
|
||||
) -> Handler<'static, DependencyMap, ResponseResult<()>, DpHandlerDescription> {
|
||||
Update::filter_inline_query().chain(dptree::endpoint(move |query: InlineQuery, bot: Bot| {
|
||||
info!("Handling inline query: `{}`", &query.query);
|
||||
|
||||
|
@ -27,7 +28,7 @@ pub fn inline_query_handler(engine: CardSearchEngine) -> Handler<'static, Depend
|
|||
next_offset: None,
|
||||
switch_pm_text: Some("How to search cards".to_string()),
|
||||
switch_pm_parameter: Some("err-no-query".to_string()),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
debug!("Querying the search engine...");
|
||||
|
@ -43,7 +44,7 @@ pub fn inline_query_handler(engine: CardSearchEngine) -> Handler<'static, Depend
|
|||
next_offset: None,
|
||||
switch_pm_text: Some("Invalid query syntax".to_string()),
|
||||
switch_pm_parameter: Some("err-invalid-query".to_string()),
|
||||
}
|
||||
};
|
||||
}
|
||||
let results = results.unwrap();
|
||||
|
||||
|
@ -58,7 +59,7 @@ pub fn inline_query_handler(engine: CardSearchEngine) -> Handler<'static, Depend
|
|||
next_offset: None,
|
||||
switch_pm_text: Some("No cards found".to_string()),
|
||||
switch_pm_parameter: Some("err-no-results".to_string()),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
debug!("Found {} cards.", &len);
|
||||
|
@ -73,7 +74,7 @@ pub fn inline_query_handler(engine: CardSearchEngine) -> Handler<'static, Depend
|
|||
next_offset: None,
|
||||
switch_pm_text: None,
|
||||
switch_pm_parameter: None,
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
async move {
|
||||
|
@ -88,7 +89,6 @@ pub fn inline_query_handler(engine: CardSearchEngine) -> Handler<'static, Depend
|
|||
}))
|
||||
}
|
||||
|
||||
|
||||
const WELCOME_MESSAGE: &'static str = r#"
|
||||
👋 Hi! I'm a robotic poro who can search for Legends of Runeterra cards to send them in chats!
|
||||
|
||||
|
@ -107,9 +107,9 @@ Have a fun time searching!
|
|||
<i>@patchedporobot isn't endorsed by Riot Games and doesn't reflect the views or opinions of Riot Games or anyone officially involved in producing or managing Riot Games properties. Riot Games, and all associated properties are trademarks or registered trademarks of Riot Games, Inc.</i>
|
||||
"#;
|
||||
|
||||
|
||||
/// Handle all messages by replying with the help text.
|
||||
pub fn message_handler() -> Handler<'static, DependencyMap, ResponseResult<()>, DpHandlerDescription> {
|
||||
pub fn message_handler() -> Handler<'static, DependencyMap, ResponseResult<()>, DpHandlerDescription>
|
||||
{
|
||||
Update::filter_message().chain(dptree::endpoint(move |message: Message, bot: Bot| {
|
||||
info!("Handling private message: `{:?}`", &message.text());
|
||||
|
||||
|
@ -123,7 +123,7 @@ pub fn message_handler() -> Handler<'static, DependencyMap, ResponseResult<()>,
|
|||
protect_content: None,
|
||||
reply_to_message_id: None,
|
||||
allow_sending_without_reply: None,
|
||||
reply_markup: None
|
||||
reply_markup: None,
|
||||
};
|
||||
|
||||
async move {
|
||||
|
@ -136,4 +136,4 @@ pub fn message_handler() -> Handler<'static, DependencyMap, ResponseResult<()>,
|
|||
respond(())
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,16 @@
|
|||
//!
|
||||
//! [inline mode]: https://core.telegram.org/bots/api#inline-mode
|
||||
|
||||
use teloxide::types::{InlineQueryResult, InlineQueryResultPhoto, ParseMode};
|
||||
use crate::data::corebundle::globals::LocalizedGlobalsIndexes;
|
||||
use crate::data::setbundle::card::Card;
|
||||
use crate::telegram::display::display_card;
|
||||
|
||||
use teloxide::types::{InlineQueryResult, InlineQueryResultPhoto, ParseMode};
|
||||
|
||||
/// Converts a [Card] into a [InlineQueryResult].
|
||||
pub fn card_to_inlinequeryresult(globals: &LocalizedGlobalsIndexes, card: &Card) -> InlineQueryResult {
|
||||
pub fn card_to_inlinequeryresult(
|
||||
globals: &LocalizedGlobalsIndexes,
|
||||
card: &Card,
|
||||
) -> InlineQueryResult {
|
||||
InlineQueryResult::Photo(InlineQueryResultPhoto {
|
||||
id: card.code.to_owned(),
|
||||
title: Some(card.name.to_owned()),
|
||||
|
@ -18,16 +20,17 @@ pub fn card_to_inlinequeryresult(globals: &LocalizedGlobalsIndexes, card: &Card)
|
|||
photo_url: card
|
||||
.main_art()
|
||||
.expect("Card to have at least one illustration")
|
||||
.card_jpg().parse()
|
||||
.card_jpg()
|
||||
.parse()
|
||||
.expect("Card to have a valid card_jpg URL"),
|
||||
thumb_url: card
|
||||
.main_art()
|
||||
.expect("Card to have at least one illustration")
|
||||
.card_jpg().parse()
|
||||
.card_jpg()
|
||||
.parse()
|
||||
.expect("Card to have a valid card_jpg URL"),
|
||||
photo_width: Some(680),
|
||||
photo_height: Some(1024),
|
||||
|
||||
description: None,
|
||||
caption_entities: None,
|
||||
reply_markup: None,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
//! This module defines the [`main`] function for [`patched_porobot_telegram`].
|
||||
|
||||
use std::path::PathBuf;
|
||||
use log::*;
|
||||
use crate::data::setbundle::card::{Card, CardIndex};
|
||||
use crate::data::corebundle::CoreBundle;
|
||||
use crate::data::setbundle::SetBundle;
|
||||
use crate::data::corebundle::globals::LocalizedGlobalsIndexes;
|
||||
use crate::data::corebundle::CoreBundle;
|
||||
use crate::data::setbundle::card::{Card, CardIndex};
|
||||
use crate::data::setbundle::SetBundle;
|
||||
use crate::search::cardsearch::CardSearchEngine;
|
||||
use crate::telegram::handler::{inline_query_handler, message_handler};
|
||||
use log::*;
|
||||
use std::path::PathBuf;
|
||||
use teloxide::prelude::*;
|
||||
|
||||
/// The main function that [`patched_porobot_telegram`] should run when it's started.
|
||||
|
@ -16,13 +16,20 @@ pub async fn main() {
|
|||
debug!("Logger initialized successfully!");
|
||||
|
||||
debug!("Loading bundles...");
|
||||
let core = CoreBundle::load(&*PathBuf::from("./data/core-en_us")).expect("to be able to load `core-en_us` bundle");
|
||||
let set1 = SetBundle::load(&*PathBuf::from("./data/set1-en_us")).expect("to be able to load `set1-en_us` bundle");
|
||||
let set2 = SetBundle::load(&*PathBuf::from("./data/set2-en_us")).expect("to be able to load `set2-en_us` bundle");
|
||||
let set3 = SetBundle::load(&*PathBuf::from("./data/set3-en_us")).expect("to be able to load `set3-en_us` bundle");
|
||||
let set4 = SetBundle::load(&*PathBuf::from("./data/set4-en_us")).expect("to be able to load `set4-en_us` bundle");
|
||||
let set5 = SetBundle::load(&*PathBuf::from("./data/set5-en_us")).expect("to be able to load `set5-en_us` bundle");
|
||||
let set6 = SetBundle::load(&*PathBuf::from("./data/set6-en_us")).expect("to be able to load `set6-en_us` bundle");
|
||||
let core = CoreBundle::load(&*PathBuf::from("./data/core-en_us"))
|
||||
.expect("to be able to load `core-en_us` bundle");
|
||||
let set1 = SetBundle::load(&*PathBuf::from("./data/set1-en_us"))
|
||||
.expect("to be able to load `set1-en_us` bundle");
|
||||
let set2 = SetBundle::load(&*PathBuf::from("./data/set2-en_us"))
|
||||
.expect("to be able to load `set2-en_us` bundle");
|
||||
let set3 = SetBundle::load(&*PathBuf::from("./data/set3-en_us"))
|
||||
.expect("to be able to load `set3-en_us` bundle");
|
||||
let set4 = SetBundle::load(&*PathBuf::from("./data/set4-en_us"))
|
||||
.expect("to be able to load `set4-en_us` bundle");
|
||||
let set5 = SetBundle::load(&*PathBuf::from("./data/set5-en_us"))
|
||||
.expect("to be able to load `set5-en_us` bundle");
|
||||
let set6 = SetBundle::load(&*PathBuf::from("./data/set6-en_us"))
|
||||
.expect("to be able to load `set6-en_us` bundle");
|
||||
debug!("Loaded all bundles!");
|
||||
|
||||
debug!("Indexing globals...");
|
||||
|
@ -31,13 +38,9 @@ pub async fn main() {
|
|||
|
||||
debug!("Indexing cards...");
|
||||
let cards: Vec<Card> = [
|
||||
set1.cards,
|
||||
set2.cards,
|
||||
set3.cards,
|
||||
set4.cards,
|
||||
set5.cards,
|
||||
set6.cards
|
||||
].concat();
|
||||
set1.cards, set2.cards, set3.cards, set4.cards, set5.cards, set6.cards,
|
||||
]
|
||||
.concat();
|
||||
|
||||
let mut index = CardIndex::new();
|
||||
for card in cards {
|
||||
|
@ -52,7 +55,11 @@ pub async fn main() {
|
|||
|
||||
debug!("Creating Telegram bot with parameters from the environment...");
|
||||
let bot = Bot::from_env();
|
||||
let me = bot.get_me().send().await.expect("Telegram bot parameters to be valid");
|
||||
let me = bot
|
||||
.get_me()
|
||||
.send()
|
||||
.await
|
||||
.expect("Telegram bot parameters to be valid");
|
||||
debug!("Created Telegram bot!");
|
||||
|
||||
debug!("Creating handlers...");
|
||||
|
@ -61,10 +68,13 @@ pub async fn main() {
|
|||
.branch(message_handler());
|
||||
debug!("Created handlers!");
|
||||
|
||||
info!("@{} is ready!", &me.username.as_ref().expect("bot to have an username"));
|
||||
info!(
|
||||
"@{} is ready!",
|
||||
&me.username.as_ref().expect("bot to have an username")
|
||||
);
|
||||
Dispatcher::builder(bot, handler)
|
||||
.enable_ctrlc_handler()
|
||||
.build()
|
||||
.dispatch()
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
//! While adding new features to this module, remember that binaries [can only access the public API of the crate](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#binaries), as they considered a separate crate from the rest of the project.
|
||||
|
||||
pub mod display;
|
||||
pub mod inline;
|
||||
pub mod handler;
|
||||
pub mod inline;
|
||||
pub mod main;
|
||||
|
|
Loading…
Reference in a new issue