diff --git a/Cargo.toml b/Cargo.toml index 4bc4b65..202454e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ itertools = { version = "0.10.3" } # Not using this yet # exec pretty_env_logger = { version = "0.4.0", optional = true } glob = { version = "0.3.0", optional = true } -# schema +# data serde = { version = "1.0.140", features = ["derive"] } serde_json = { version = "1.0.82" } # search @@ -29,7 +29,7 @@ tokio = { version = "1.20.1", features = ["rt-multi-thread", "macros"], optiona # matrix [features] -# schema = [] # Always included +# data = [] # Always included exec = ["pretty_env_logger", "glob"] search = ["tantivy"] telegram = ["search", "teloxide", "reqwest", "tokio"] @@ -39,7 +39,3 @@ telegram = ["search", "teloxide", "reqwest", "tokio"] [lib] name = "patched_porobot" path = "src/lib.rs" - -[[bin]] -name = "patched_porobot_telegram" -path = "src/telegram/bin.rs" diff --git a/src/data/anybundle/metadata.rs b/src/data/anybundle/metadata.rs new file mode 100644 index 0000000..52d0c3f --- /dev/null +++ b/src/data/anybundle/metadata.rs @@ -0,0 +1,43 @@ +//! This module defines [BundleMetadata], the contents of `metadata.json`. + +use std::fs::File; +use std::path::Path; +use crate::data::outcomes::{LoadingError, LoadingResult}; + +/// A parsed `metadata.json` file from a Data Dragon Bundle. +/// +/// The specification defines more fields, but they are missing from the output files. +/// +/// > ```json +/// > { +/// > "locales": ["{string}", ], +/// > "clientHash": "{string}" +/// > "gameplayDataHash": "{string}", +/// > "timestamp": "{YYYYMMDDhhmm}", +/// > "patchlineRef": "{string}" +/// > } +/// > ``` +#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +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 +} + + +impl BundleMetadata { + /// Load a `metadata.json` file to create a [LocalizedGlobalsVecs] instance. + pub fn load(path: &Path) -> LoadingResult { + let file = File::open(path) + .map_err(LoadingError::Loading)?; + let data = serde_json::de::from_reader::(file) + .map_err(LoadingError::Parsing)?; + Ok(data) + } + + /// Get a reference to the first (and probably only) locale defined in BundleMetadata. + pub fn locale(&self) -> Option<&String> { + self.locales.get(0) + } +} \ No newline at end of file diff --git a/src/data/anybundle/mod.rs b/src/data/anybundle/mod.rs new file mode 100644 index 0000000..fd3758f --- /dev/null +++ b/src/data/anybundle/mod.rs @@ -0,0 +1,3 @@ +//! This module defines structs common to all Data Dragon Bundles. + +pub mod metadata; diff --git a/src/data/corebundle/globals.rs b/src/data/corebundle/globals.rs new file mode 100644 index 0000000..0a3ce2e --- /dev/null +++ b/src/data/corebundle/globals.rs @@ -0,0 +1,216 @@ +//! This module defines [LocalizedGlobalsVecs] and [LocalizedGlobalsIndexes], structs representing the data contained in the `globals.json` files. + +use std::fs::File; +use std::path::Path; +use crate::data::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 Legends of Runeterra Core Bundle. +/// +/// It contains a list of all vocabulary terms, keywords, regions, spell speeds, and rarities present in Legends of Runeterra. +#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct LocalizedGlobalsVecs { + #[serde(rename = "vocabTerms")] + pub vocab_terms: LocalizedVocabTermVec, + + pub keywords: LocalizedCardKeywordVec, + + pub regions: LocalizedCardRegionVec, + + #[serde(rename = "spellSpeeds")] + pub spell_speeds: LocalizedSpellSpeedVec, + + pub rarities: LocalizedCardRarityVec, + + pub sets: LocalizedCardSetVec, +} + +/// An instance of [LocalizedGlobalsVecs] which had its own fields indexed in [HashMap]s, using the respective identifiers as map keys. +/// +/// It contains a indexed list of all vocabulary terms, keywords, regions, spell speeds, and rarities present in Legends of Runeterra. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct LocalizedGlobalsIndexes { + pub vocab_terms: LocalizedVocabTermIndex, + + pub keywords: LocalizedCardKeywordIndex, + + pub regions: LocalizedCardRegionIndex, + + pub spell_speeds: LocalizedSpellSpeedIndex, + + pub rarities: LocalizedCardRarityIndex, + + pub sets: LocalizedCardSetIndex, +} + + +impl LocalizedGlobalsVecs { + /// Load a `globals.json` file to create a [LocalizedGlobalsVecs] instance. + pub fn load(path: &Path) -> LoadingResult { + let file = File::open(path) + .map_err(LoadingError::Loading)?; + let data = serde_json::de::from_reader::(file) + .map_err(LoadingError::Parsing)?; + Ok(data) + } +} + + +impl From for LocalizedGlobalsIndexes { + fn from(o: LocalizedGlobalsVecs) -> Self { + Self { + vocab_terms: { + let mut hm = LocalizedVocabTermIndex::new(); + for obj in o.vocab_terms { + hm.insert(obj.vocabterm.clone(), obj); + } + hm + }, + keywords: { + let mut hm = LocalizedCardKeywordIndex::new(); + for obj in o.keywords { + hm.insert(obj.keyword, obj); + } + hm + }, + regions: { + let mut hm = LocalizedCardRegionIndex::new(); + for obj in o.regions { + hm.insert(obj.region, obj); + } + hm + }, + spell_speeds: { + let mut hm = LocalizedSpellSpeedIndex::new(); + for obj in o.spell_speeds { + hm.insert(obj.spell_speed, obj); + } + hm + }, + rarities: { + let mut hm = LocalizedCardRarityIndex::new(); + for obj in o.rarities { + hm.insert(obj.rarity, obj); + } + hm + }, + sets: { + let mut hm = LocalizedCardSetIndex::new(); + for obj in o.sets { + hm.insert(obj.set, obj); + } + hm + }, + } + } +} + + +#[cfg(test)] +mod tests { + use super::*; + use crate::data::setbundle::keyword::CardKeyword; + use crate::data::setbundle::rarity::CardRarity; + use crate::data::setbundle::region::CardRegion; + use crate::data::setbundle::set::CardSet; + use crate::data::setbundle::speed::SpellSpeed; + + #[test] + fn deserialize() { + assert_eq!( + serde_json::de::from_str::<'static, LocalizedGlobalsVecs>(r#" + { + "vocabTerms": [ + { + "description": "When you summon this, it gets its allegiance bonus if the top card of your deck matches its region.", + "name": "Allegiance", + "nameRef": "Allegiance" + } + ], + "keywords": [ + { + "description": "Inflicts damage beyond what would kill the target(s) to the enemy Nexus.", + "name": "Overwhelm", + "nameRef": "SpellOverwhelm" + } + ], + "regions": [ + { + "abbreviation": "NX", + "iconAbsolutePath": "http://dd.b.pvp.net/3_11_0/core/en_us/img/regions/icon-noxus.png", + "name": "Noxus", + "nameRef": "Noxus" + } + ], + "spellSpeeds": [ + { + "name": "Slow", + "nameRef": "Slow" + } + ], + "rarities": [ + { + "name": "COMMON", + "nameRef": "Common" + } + ], + "sets": [ + { + "iconAbsolutePath": "http://dd.b.pvp.net/3_11_0/core/en_us/img/sets/set3_crispmip.png", + "name": "Call of the Mountain", + "nameRef": "Set3" + } + ] + } + "#).unwrap(), + LocalizedGlobalsVecs { + vocab_terms: vec![ + vocabterm::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![ + keyword::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![ + region::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![ + speed::LocalizedSpellSpeed { + spell_speed: SpellSpeed::Slow, + name: "Slow".to_string(), + } + ], + rarities: vec![ + rarity::LocalizedCardRarity { + rarity: CardRarity::Common, + name: "COMMON".to_string(), + } + ], + sets: vec![ + set::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(), + } + ] + } + ) + } +} diff --git a/src/schema/corebundle/keyword.rs b/src/data/corebundle/keyword.rs similarity index 66% rename from src/schema/corebundle/keyword.rs rename to src/data/corebundle/keyword.rs index 4a2c4e8..df5ed22 100644 --- a/src/schema/corebundle/keyword.rs +++ b/src/data/corebundle/keyword.rs @@ -1,10 +1,11 @@ //! This module defines [CoreKeyword]. -use crate::schema::setbundle::CardKeyword; +use std::collections::HashMap; +use crate::data::setbundle::keyword::CardKeyword; /// A Legends of Runeterra [CardKeyword], and its associated localization. #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct CoreKeyword { +pub struct LocalizedCardKeyword { /// The [CardKeyword] these strings refer to. #[serde(rename = "nameRef")] pub keyword: CardKeyword, @@ -16,24 +17,27 @@ pub struct CoreKeyword { pub description: String, } +/// How [LocalizedCardKeyword]s appear in `global.json` files. +pub type LocalizedCardKeywordVec = Vec; +/// An index of [LocalizedCardKeyword]s, with [LocalizedCardKeyword::keyword]s as keys. +pub type LocalizedCardKeywordIndex = HashMap; + #[cfg(test)] mod tests { - use crate::schema::setbundle::CardKeyword; - - use super::CoreKeyword; + use super::*; #[test] fn deserialize() { assert_eq!( - serde_json::de::from_str::<'static, CoreKeyword>(r#" + serde_json::de::from_str::<'static, LocalizedCardKeyword>(r#" { "description": "Inflicts damage beyond what would kill the target(s) to the enemy Nexus.", "name": "Overwhelm", "nameRef": "SpellOverwhelm" } "#).unwrap(), - CoreKeyword { + LocalizedCardKeyword { keyword: CardKeyword::SpellOverwhelm, name: "Overwhelm".to_string(), description: "Inflicts damage beyond what would kill the target(s) to the enemy Nexus.".to_string(), diff --git a/src/data/corebundle/mod.rs b/src/data/corebundle/mod.rs new file mode 100644 index 0000000..678791e --- /dev/null +++ b/src/data/corebundle/mod.rs @@ -0,0 +1,45 @@ +//! This module defines the types used in Data Dragon [Core Bundles](https://developer.riotgames.com/docs/lor#data-dragon_core-bundles). + +use std::path::Path; +use super::anybundle::metadata::BundleMetadata; +use super::outcomes::{LoadingError, LoadingResult}; + +pub mod globals; +pub mod vocabterm; +pub mod keyword; +pub mod region; +pub mod speed; +pub mod rarity; +pub mod set; + + +/// A parsed [Core Bundle](https://developer.riotgames.com/docs/lor#data-dragon_core-bundles). +pub struct CoreBundle { + /// The contents of the `metadata.json` file. + pub metadata: BundleMetadata, + + /// The contents of the `[locale]/data/globals-[locale].json` file. + pub globals: globals::LocalizedGlobalsVecs, +} + + +impl CoreBundle { + /// Load a Core Bundle directory to create a [CoreBundle] instance. + pub fn load(bundle_path: &Path) -> LoadingResult { + let metadata = BundleMetadata::load( + &bundle_path + .join("metadata.json") + )?; + + let locale = metadata.locale().ok_or(LoadingError::Using)?; + + let globals = globals::LocalizedGlobalsVecs::load( + &bundle_path + .join(&locale) + .join("data") + .join(format!("globals-{}.json", &locale)) + )?; + + Ok(CoreBundle {metadata, globals}) + } +} diff --git a/src/schema/corebundle/rarity.rs b/src/data/corebundle/rarity.rs similarity index 57% rename from src/schema/corebundle/rarity.rs rename to src/data/corebundle/rarity.rs index af0b162..f0c4b86 100644 --- a/src/schema/corebundle/rarity.rs +++ b/src/data/corebundle/rarity.rs @@ -1,10 +1,11 @@ //! This module defines [CoreRarity]. -use crate::schema::setbundle::CardRarity; +use std::collections::HashMap; +use crate::data::setbundle::rarity::CardRarity; /// A Legends of Runeterra [CardRarity], and its associated localization. #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct CoreRarity { +pub struct LocalizedCardRarity { /// The [CardRarity] these strings refer to. #[serde(rename = "nameRef")] pub rarity: CardRarity, @@ -13,23 +14,26 @@ pub struct CoreRarity { pub name: String, } +/// How [LocalizedCardRarity]s appear in `global.json` files. +pub type LocalizedCardRarityVec = Vec; +/// An index of [LocalizedCardRarity]s, with [LocalizedCardRarity::rarity]s as keys. +pub type LocalizedCardRarityIndex = HashMap; + #[cfg(test)] mod tests { - use crate::schema::setbundle::CardRarity; - - use super::CoreRarity; + use super::*; #[test] fn deserialize() { assert_eq!( - serde_json::de::from_str::<'static, CoreRarity>(r#" + serde_json::de::from_str::<'static, LocalizedCardRarity>(r#" { "name": "COMMON", "nameRef": "Common" } "#).unwrap(), - CoreRarity { + LocalizedCardRarity { rarity: CardRarity::Common, name: "COMMON".to_string(), } diff --git a/src/schema/corebundle/region.rs b/src/data/corebundle/region.rs similarity index 71% rename from src/schema/corebundle/region.rs rename to src/data/corebundle/region.rs index cda127d..315dfea 100644 --- a/src/schema/corebundle/region.rs +++ b/src/data/corebundle/region.rs @@ -1,10 +1,11 @@ //! This module defines [CoreRegion]. -use crate::schema::setbundle::CardRegion; +use std::collections::HashMap; +use crate::data::setbundle::region::CardRegion; /// A Legends of Runeterra [CardRegion], and its associated localization. #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct CoreRegion { +pub struct LocalizedCardRegion { /// The [CardRegion] these strings refer to. #[serde(rename = "nameRef")] pub region: CardRegion, @@ -22,17 +23,20 @@ pub struct CoreRegion { pub icon_png: String, } +/// How [LocalizedCardRegion]s appear in `global.json` files. +pub type LocalizedCardRegionVec = Vec; +/// An index of [LocalizedCardRegion]s, with [LocalizedCardRegion::region]s as keys. +pub type LocalizedCardRegionIndex = HashMap; + #[cfg(test)] mod tests { - use crate::schema::setbundle::CardRegion; - - use super::CoreRegion; + use super::*; #[test] fn deserialize() { assert_eq!( - serde_json::de::from_str::<'static, CoreRegion>(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", @@ -40,7 +44,7 @@ mod tests { "nameRef": "Noxus" } "#).unwrap(), - CoreRegion { + LocalizedCardRegion { region: CardRegion::Noxus, name: "Noxus".to_string(), abbreviation: "NX".to_string(), diff --git a/src/schema/corebundle/set.rs b/src/data/corebundle/set.rs similarity index 68% rename from src/schema/corebundle/set.rs rename to src/data/corebundle/set.rs index d4a7bfa..a1bc307 100644 --- a/src/schema/corebundle/set.rs +++ b/src/data/corebundle/set.rs @@ -1,10 +1,11 @@ //! This module defines [CoreSet]. -use crate::schema::setbundle::CardSet; +use std::collections::HashMap; +use crate::data::setbundle::set::CardSet; /// A Legends of Runeterra [CardSet], and its associated localization. #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct CoreSet { +pub struct LocalizedCardSet { /// The [CardSet] these strings refer to. #[serde(rename = "nameRef")] pub set: CardSet, @@ -17,24 +18,27 @@ pub struct CoreSet { pub icon_png: String, } +/// How [LocalizedCardSet]s appear in `global.json` files. +pub type LocalizedCardSetVec = Vec; +/// An index of [LocalizedCardSet]s, with [LocalizedCardSet::set]s as keys. +pub type LocalizedCardSetIndex = HashMap; + #[cfg(test)] mod tests { - use crate::schema::setbundle::CardSet; - - use super::CoreSet; + use super::*; #[test] fn deserialize() { assert_eq!( - serde_json::de::from_str::<'static, CoreSet>(r#" + serde_json::de::from_str::<'static, LocalizedCardSet>(r#" { "iconAbsolutePath": "http://dd.b.pvp.net/3_11_0/core/en_us/img/sets/set3_crispmip.png", "name": "Call of the Mountain", "nameRef": "Set3" } "#).unwrap(), - CoreSet { + 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(), diff --git a/src/schema/corebundle/speed.rs b/src/data/corebundle/speed.rs similarity index 58% rename from src/schema/corebundle/speed.rs rename to src/data/corebundle/speed.rs index fbeca2a..132f9f8 100644 --- a/src/schema/corebundle/speed.rs +++ b/src/data/corebundle/speed.rs @@ -1,10 +1,11 @@ //! This module defines [CoreSpellSpeed]. -use crate::schema::setbundle::SpellSpeed; +use std::collections::HashMap; +use crate::data::setbundle::speed::SpellSpeed; /// A Legends of Runeterra [SpellSpeed], and its associated localization. #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct CoreSpellSpeed { +pub struct LocalizedSpellSpeed { /// The [SpellSpeed] these strings refer to. #[serde(rename = "nameRef")] pub spell_speed: SpellSpeed, @@ -13,23 +14,26 @@ pub struct CoreSpellSpeed { pub name: String, } +/// How [LocalizedSpellSpeed]s appear in `global.json` files. +pub type LocalizedSpellSpeedVec = Vec; +/// An index of [LocalizedSpellSpeed]s, with [LocalizedSpellSpeed::spell_speed]s as keys. +pub type LocalizedSpellSpeedIndex = HashMap; + #[cfg(test)] mod tests { - use crate::schema::setbundle::SpellSpeed; - - use super::CoreSpellSpeed; + use super::*; #[test] fn deserialize() { assert_eq!( - serde_json::de::from_str::<'static, CoreSpellSpeed>(r#" + serde_json::de::from_str::<'static, LocalizedSpellSpeed>(r#" { "name": "Slow", "nameRef": "Slow" } "#).unwrap(), - CoreSpellSpeed { + LocalizedSpellSpeed { spell_speed: SpellSpeed::Slow, name: "Slow".to_string(), } diff --git a/src/schema/corebundle/vocabterm.rs b/src/data/corebundle/vocabterm.rs similarity index 63% rename from src/schema/corebundle/vocabterm.rs rename to src/data/corebundle/vocabterm.rs index 77a3a1c..d950e73 100644 --- a/src/schema/corebundle/vocabterm.rs +++ b/src/data/corebundle/vocabterm.rs @@ -1,16 +1,14 @@ //! This module defines [CoreVocabTerm]. +use std::collections::HashMap; +use std::hash::Hash; /// A Legends of Runeterra vocabulary term, and its associated localization. /// -/// I'm not sure where these are used, other than in in-game tooltips. -/// -/// TODO: Find out where these are used. +/// Vocabulary terms are used in [XML tags of card descriptions](crate::data::setbundle::card::Card::localized_description_xml) to provide tooltips about game mechanics. #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct CoreVocabTerm { +pub struct LocalizedVocabTerm { /// The internal name used by the vocabulary term. - /// - /// TODO: Map these to an enum. #[serde(rename = "nameRef")] pub vocabterm: String, @@ -21,22 +19,27 @@ pub struct CoreVocabTerm { pub description: String, } +/// How [LocalizedVocabTerm]s appear in `global.json` files. +pub type LocalizedVocabTermVec = Vec; +/// An index of [LocalizedVocabTerm]s, with [LocalizedVocabTerm::vocabterm]s as keys. +pub type LocalizedVocabTermIndex = HashMap; + #[cfg(test)] mod tests { - use super::CoreVocabTerm; + use super::*; #[test] fn deserialize() { assert_eq!( - serde_json::de::from_str::<'static, CoreVocabTerm>(r#" + serde_json::de::from_str::<'static, LocalizedVocabTerm>(r#" { "description": "When you summon this, it gets its allegiance bonus if the top card of your deck matches its region.", "name": "Allegiance", "nameRef": "Allegiance" } "#).unwrap(), - CoreVocabTerm { + 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(), diff --git a/src/schema/mod.rs b/src/data/mod.rs similarity index 87% rename from src/schema/mod.rs rename to src/data/mod.rs index 9950cdf..961270a 100644 --- a/src/schema/mod.rs +++ b/src/data/mod.rs @@ -3,3 +3,4 @@ pub mod corebundle; pub mod setbundle; pub mod anybundle; +pub mod outcomes; diff --git a/src/data/outcomes.rs b/src/data/outcomes.rs new file mode 100644 index 0000000..deb1947 --- /dev/null +++ b/src/data/outcomes.rs @@ -0,0 +1,8 @@ +pub enum LoadingError { + Checking, + Loading(std::io::Error), + Parsing(serde_json::Error), + Using, +} + +pub type LoadingResult = Result; diff --git a/src/schema/setbundle/art.rs b/src/data/setbundle/art.rs similarity index 100% rename from src/schema/setbundle/art.rs rename to src/data/setbundle/art.rs diff --git a/src/schema/setbundle/card.rs b/src/data/setbundle/card.rs similarity index 98% rename from src/schema/setbundle/card.rs rename to src/data/setbundle/card.rs index 2e121b0..71039c2 100644 --- a/src/schema/setbundle/card.rs +++ b/src/data/setbundle/card.rs @@ -1,8 +1,13 @@ //! Module defining [Card]. - use std::collections::HashMap; -use super::*; +use super::r#type::CardType; +use super::art::CardArt; +use super::keyword::CardKeyword; +use super::rarity::CardRarity; +use super::region::CardRegion; +use super::speed::SpellSpeed; +use super::set::CardSet; /// A single Legends of Runeterra card as represented in a `set.json` file. /// @@ -141,7 +146,6 @@ pub struct Card { pub supertype: String, } - impl Card { /// Get references to the cards associated with this one, given an [HashMap] of cards indexed by code. pub fn associated_cards<'c, 'hm: 'c>(&'c self, hashmap: &'hm HashMap) -> impl Iterator> + 'c { diff --git a/src/schema/setbundle/keyword.rs b/src/data/setbundle/keyword.rs similarity index 96% rename from src/schema/setbundle/keyword.rs rename to src/data/setbundle/keyword.rs index 08a8828..45846a6 100644 --- a/src/schema/setbundle/keyword.rs +++ b/src/data/setbundle/keyword.rs @@ -1,9 +1,6 @@ //! Module defining [CardKeyword]. - -use std::collections::HashMap; - -use crate::schema::corebundle::CoreKeyword; +use crate::data::corebundle::keyword::{LocalizedCardKeyword, LocalizedCardKeywordIndex}; /// A keyword which cards can have. /// @@ -337,12 +334,13 @@ pub enum CardKeyword { Unsupported, } - impl CardKeyword { - /// Get localized text about the keyword from [crate::schema::corebundle] data. + /// Get the [LocalizedCardKeyword] associated with this [CardKeyword]. /// - /// Returns `None` if no matching [CoreKeyword] was found, for example for [CardKeyword::Unsupported] keywords. - pub fn localized<'hm>(&self, hm: &'hm HashMap) -> Option<&'hm CoreKeyword> { + /// 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> { hm.get(&self) } } diff --git a/src/data/setbundle/mod.rs b/src/data/setbundle/mod.rs new file mode 100644 index 0000000..d2bf8c4 --- /dev/null +++ b/src/data/setbundle/mod.rs @@ -0,0 +1,53 @@ +//! This module defines the types used in Data Dragon [Set Bundles](https://developer.riotgames.com/docs/lor#data-dragon_set-bundles). + +use std::fs::File; +use std::path::Path; +use super::anybundle::metadata::BundleMetadata; +use super::outcomes::{LoadingError, LoadingResult}; + +pub mod card; +pub mod art; +pub mod r#type; +pub mod rarity; +pub mod region; +pub mod set; +pub mod speed; +pub mod keyword; + + +/// A parsed [Set Bundle](https://developer.riotgames.com/docs/lor#data-dragon_set-bundles). +pub struct SetBundle { + /// The contents of the `metadata.json` file. + pub metadata: BundleMetadata, + + /// The contents of the `[locale]/data/globals-[locale].json` file. + pub cards: Vec, +} + + +impl SetBundle { + /// Load a Set Bundle directory to create a [SetBundle] instance. + pub fn load(bundle_path: &Path) -> LoadingResult { + let metadata = BundleMetadata::load( + &bundle_path + .join("metadata.json") + )?; + + let locale = metadata.locale().ok_or(LoadingError::Using)?; + + let mut filename = bundle_path.file_name().ok_or(LoadingError::Checking)?.to_os_string(); + filename.push(".json"); + + let cards = File::open( + &bundle_path + .join(&locale) + .join("data") + .join(filename) + ).map_err(LoadingError::Loading)?; + + let cards = serde_json::de::from_reader::>(cards) + .map_err(LoadingError::Parsing)?; + + Ok(SetBundle {metadata, cards}) + } +} diff --git a/src/schema/setbundle/rarity.rs b/src/data/setbundle/rarity.rs similarity index 74% rename from src/schema/setbundle/rarity.rs rename to src/data/setbundle/rarity.rs index 4427ade..cea9979 100644 --- a/src/schema/setbundle/rarity.rs +++ b/src/data/setbundle/rarity.rs @@ -1,9 +1,6 @@ //! Module defining [CardRarity]. - -use std::collections::HashMap; - -use crate::schema::corebundle::CoreRarity; +use crate::data::corebundle::rarity::{LocalizedCardRarity, LocalizedCardRarityIndex}; /// A possible [super::Card] rarity. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] @@ -24,12 +21,13 @@ pub enum CardRarity { Champion, } - impl CardRarity { - /// Get localized text about the rarity from [crate::schema::corebundle] data. + /// Get the [LocalizedCardRarity] associated with this [CardRarity]. /// - /// Returns `None` if no matching [CoreRarity] was found, for example if the hashmap is incomplete. - pub fn localized<'hm>(&self, hm: &'hm HashMap) -> Option<&'hm CoreRarity> { + /// 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> { hm.get(&self) } } diff --git a/src/schema/setbundle/region.rs b/src/data/setbundle/region.rs similarity index 84% rename from src/schema/setbundle/region.rs rename to src/data/setbundle/region.rs index a479f43..26d1563 100644 --- a/src/schema/setbundle/region.rs +++ b/src/data/setbundle/region.rs @@ -1,9 +1,6 @@ //! Module defining [CardRegion]. - -use std::collections::HashMap; - -use crate::schema::corebundle::CoreRegion; +use crate::data::corebundle::region::{LocalizedCardRegion, LocalizedCardRegionIndex}; /// A region to which [super::Card]s can belong to. /// @@ -45,12 +42,13 @@ pub enum CardRegion { Unsupported, } - impl CardRegion { - /// Get localized text about the region from [crate::schema::corebundle] data. + /// Get the [LocalizedCardRegion] associated with this [CardRegion]. /// - /// Returns `None` if no matching [CoreRegion] was found, for example for [CardRegion::Unsupported] regions. - pub fn localized<'hm>(&self, hm: &'hm HashMap) -> Option<&'hm CoreRegion> { + /// Returns [Option::None] if no matching [LocalizedCardRegion] was found, for example for [CardRegion::Unsupported] regions. + /// + /// Equivalent to calling [LocalizedCardRegionIndex::get]. + pub fn localized<'hm>(&self, hm: &'hm LocalizedCardRegionIndex) -> Option<&'hm LocalizedCardRegion> { hm.get(&self) } } diff --git a/src/schema/setbundle/set.rs b/src/data/setbundle/set.rs similarity index 82% rename from src/schema/setbundle/set.rs rename to src/data/setbundle/set.rs index 25338d5..84fd143 100644 --- a/src/schema/setbundle/set.rs +++ b/src/data/setbundle/set.rs @@ -1,9 +1,6 @@ //! Module defining [CardSet]. - -use std::collections::HashMap; - -use crate::schema::corebundle::CoreSet; +use crate::data::corebundle::set::{LocalizedCardSet, LocalizedCardSetIndex}; /// The release set a [super::Card] may belong to. /// @@ -44,12 +41,13 @@ pub enum CardSet { Unsupported, } - impl CardSet { - /// Get localized text about the set from [crate::schema::corebundle] data. + /// Get the [LocalizedCardSet] associated with this [CardSet]. /// - /// Returns `None` if no matching [CoreSet] was found, for example for [CardSet::Unsupported] sets. - pub fn localized<'hm>(&self, hm: &'hm HashMap) -> Option<&'hm CoreSet> { + /// Returns [Option::None] if no matching [LocalizedCardSet] was found, for example for [CardSet::Unsupported] sets. + /// + /// Equivalent to calling [LocalizedCardSetIndex::get]. + pub fn localized<'hm>(&self, hm: &'hm LocalizedCardSetIndex) -> Option<&'hm LocalizedCardSet> { hm.get(&self) } } diff --git a/src/schema/setbundle/speed.rs b/src/data/setbundle/speed.rs similarity index 72% rename from src/schema/setbundle/speed.rs rename to src/data/setbundle/speed.rs index aec7e81..8921dda 100644 --- a/src/schema/setbundle/speed.rs +++ b/src/data/setbundle/speed.rs @@ -1,9 +1,6 @@ //! Module defining [SpellSpeed]. - -use std::collections::HashMap; - -use crate::schema::corebundle::CoreSpellSpeed; +use crate::data::corebundle::speed::{LocalizedSpellSpeed, LocalizedSpellSpeedIndex}; /// A possible spell speed. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] @@ -19,12 +16,13 @@ pub enum SpellSpeed { Burst, } - impl SpellSpeed { - /// Get localized text about the speed from [crate::schema::corebundle] data. + /// Get the [LocalizedSpellSpeed] associated with this [SpellSpeed]. /// - /// Returns `None` if no matching [CoreSpellSpeed] was found, for example if the hashmap is incomplete. - pub fn localized<'hm>(&self, hm: &'hm HashMap) -> Option<&'hm CoreSpellSpeed> { + /// 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> { hm.get(&self) } } diff --git a/src/schema/setbundle/type.rs b/src/data/setbundle/type.rs similarity index 100% rename from src/schema/setbundle/type.rs rename to src/data/setbundle/type.rs diff --git a/src/lib.rs b/src/lib.rs index e668f94..adcb05d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,4 @@ -pub mod schema; -pub mod load; +pub mod data; #[cfg(feature = "search")] pub mod search; diff --git a/src/load/corebundle.rs b/src/load/corebundle.rs deleted file mode 100644 index aaf2714..0000000 --- a/src/load/corebundle.rs +++ /dev/null @@ -1,100 +0,0 @@ -//! This module provides ways to load official data files from Riot Games' [Core Bundles](https://developer.riotgames.com/docs/lor#data-dragon_core-bundles) into Rust structs. - -use std::collections::HashMap; -use std::io::Read; - -use crate::schema::corebundle::*; -use crate::schema::setbundle::*; - -/// Deserialize a `globals.json` file into a [CoreGlobals] struct. -pub fn globalsjson_to_coreglobals(r: R) -> serde_json::Result - where R: Read -{ - serde_json::de::from_reader::(r) -} - - -/// Convert a [Vec] of [CoreVocabTerm]s into a [HashMap] of [CoreVocabTerm]s, indexed by their [CoreVocabTerm::vocabterm]. -pub fn vocabtermvec_to_vocabtermhashmap(v: Vec) -> HashMap { - let mut hm = HashMap::::new(); - for vocabterm in v { - hm.insert(vocabterm.vocabterm.clone(), vocabterm); - } - hm -} - - -/// Convert a [Vec] of [CoreKeyword]s into a [HashMap] of [CoreKeyword]s, indexed by their [CoreKeyword::keyword]. -pub fn keywordvec_to_keywordhashmap(v: Vec) -> HashMap { - let mut hm = HashMap::::new(); - for keyword in v { - hm.insert(keyword.keyword, keyword); - } - hm -} - - -/// Convert a [Vec] of [CoreRegion]s into a [HashMap] of [CoreRegion]s, indexed by their [CoreRegion::region]. -pub fn regionvec_to_regionhashmap(v: Vec) -> HashMap { - let mut hm = HashMap::::new(); - for region in v { - hm.insert(region.region, region); - } - hm -} - - -/// Convert a [Vec] of [CoreSpellSpeed]s into a [HashMap] of [CoreSpellSpeed]s, indexed by their [CoreSpellSpeed::spell_speed]. -pub fn spellspeedvec_to_spellspeedhashmap(v: Vec) -> HashMap { - let mut hm = HashMap::::new(); - for spell_speed in v { - hm.insert(spell_speed.spell_speed, spell_speed); - } - hm -} - - -/// Convert a [Vec] of [CoreRarity]s into a [HashMap] of [CoreRarity]s, indexed by their [CoreRarity::spell_speed]. -pub fn rarityvec_to_rarityhashmap(v: Vec) -> HashMap { - let mut hm = HashMap::::new(); - for rarity in v { - hm.insert(rarity.rarity, rarity); - } - hm -} - - -/// Convert a [Vec] of [CoreSet]s into a [HashMap] of [CoreSet]s, indexed by their [CoreSet::set]. -pub fn setvec_to_sethashmap(v: Vec) -> HashMap { - let mut hm = HashMap::::new(); - for set in v { - hm.insert(set.set, set); - } - hm -} - - -/// A [CoreGlobals] struct where items are [HashMap]s mapping identifiers to the data they belong to. -pub struct MappedGlobals { - pub vocab_terms: HashMap, - pub keywords: HashMap, - pub regions: HashMap, - pub spell_speeds: HashMap, - pub rarities: HashMap, - pub sets: HashMap, -} - - -/// Trait allowing easy conversion from [CoreGlobals] to [MappedGlobals]. -impl From for MappedGlobals { - fn from(cg: CoreGlobals) -> Self { - MappedGlobals { - vocab_terms: vocabtermvec_to_vocabtermhashmap(cg.vocab_terms), - keywords: keywordvec_to_keywordhashmap(cg.keywords), - regions: regionvec_to_regionhashmap(cg.regions), - spell_speeds: spellspeedvec_to_spellspeedhashmap(cg.spell_speeds), - rarities: rarityvec_to_rarityhashmap(cg.rarities), - sets: setvec_to_sethashmap(cg.sets), - } - } -} diff --git a/src/load/mod.rs b/src/load/mod.rs deleted file mode 100644 index 7e57ff7..0000000 --- a/src/load/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! This module provides ways to load official data files from Riot Games' [Data Dragon](https://developer.riotgames.com/docs/lor#data-dragon) into Rust structs. - -pub mod corebundle; -pub mod setbundle; diff --git a/src/load/setbundle.rs b/src/load/setbundle.rs deleted file mode 100644 index 4147c22..0000000 --- a/src/load/setbundle.rs +++ /dev/null @@ -1,239 +0,0 @@ -//! This module provides ways to load official data files from Riot Games' [Set Bundles](https://developer.riotgames.com/docs/lor#data-dragon_set-bundles) into Rust structs. - -use std::collections::HashMap; -use std::io::Read; - -use crate::schema::setbundle::*; - -/// Deserialize a `set.json` file into a [Vec] of [Card]s. -pub fn setjson_to_cardvec(r: R) -> serde_json::Result> - where R: Read -{ - serde_json::de::from_reader::>(r) -} - - -/// Convert a [Vec] of [Card]s (probably from [setjson_to_vec]) into a [HashMap] of [Card]s, indexed by their [Card::code]. -pub fn cardvec_to_cardhashmap(v: Vec) -> HashMap { - let mut hm = HashMap::::new(); - for card in v { - hm.insert(card.code.clone(), card); - } - hm -} - - -#[cfg(test)] -#[allow(deprecated)] -mod tests { - use std::collections::HashMap; - - use crate::schema::setbundle::*; - - use super::cardvec_to_cardhashmap; - use super::setjson_to_cardvec; - - const TEST_SETJSON: &str = r#" - [ - { - "associatedCards": [], - "associatedCardRefs": [], - "assets": [ - { - "gameAbsolutePath": "http://dd.b.pvp.net/3_11_0/set1/en_us/img/cards/01IO012.png", - "fullAbsolutePath": "http://dd.b.pvp.net/3_11_0/set1/en_us/img/cards/01IO012-full.png" - } - ], - "regions": [ - "Ionia" - ], - "regionRefs": [ - "Ionia" - ], - "attack": 0, - "cost": 2, - "health": 0, - "description": "Give an ally +2|+0 or +0|+3 this round.", - "descriptionRaw": "Give an ally +2|+0 or +0|+3 this round.", - "levelupDescription": "", - "levelupDescriptionRaw": "", - "flavorText": "\"Never fear change. It will question you, test your limits. It is our greatest teacher.\" - Karma", - "artistName": "SIXMOREVODKA", - "name": "Twin Disciplines", - "cardCode": "01IO012", - "keywords": [ - "Burst" - ], - "keywordRefs": [ - "Burst" - ], - "spellSpeed": "Burst", - "spellSpeedRef": "Burst", - "rarity": "COMMON", - "rarityRef": "Common", - "subtypes": [], - "supertype": "", - "type": "Spell", - "collectible": true, - "set": "Set1" - }, - { - "associatedCards": [], - "associatedCardRefs": [], - "assets": [ - { - "gameAbsolutePath": "http://dd.b.pvp.net/3_11_0/set1/en_us/img/cards/01IO012T2.png", - "fullAbsolutePath": "http://dd.b.pvp.net/3_11_0/set1/en_us/img/cards/01IO012T2-full.png" - } - ], - "regions": [ - "Ionia" - ], - "regionRefs": [ - "Ionia" - ], - "attack": 0, - "cost": 2, - "health": 0, - "description": "Give an ally +0|+3 this round.", - "descriptionRaw": "Give an ally +0|+3 this round.", - "levelupDescription": "", - "levelupDescriptionRaw": "", - "flavorText": "", - "artistName": "SIXMOREVODKA", - "name": "Discipline of Fortitude", - "cardCode": "01IO012T2", - "keywords": [ - "Burst" - ], - "keywordRefs": [ - "Burst" - ], - "spellSpeed": "Burst", - "spellSpeedRef": "Burst", - "rarity": "None", - "rarityRef": "None", - "subtypes": [], - "supertype": "", - "type": "Spell", - "collectible": false, - "set": "Set1" - } - ] - "#; - - fn expected_card_1() -> Card { - Card { - code: "01IO012".to_string(), - name: "Twin Disciplines".to_string(), - r#type: CardType::Spell, - set: CardSet::Foundations, - rarity: CardRarity::Common, - collectible: true, - regions: vec![ - CardRegion::Ionia, - ], - localized_regions: vec![ - "Ionia".to_string(), - ], - art: vec![ - CardArt { - card_png: "http://dd.b.pvp.net/3_11_0/set1/en_us/img/cards/01IO012.png".to_string(), - full_png: "http://dd.b.pvp.net/3_11_0/set1/en_us/img/cards/01IO012-full.png".to_string(), - } - ], - attack: 0, - cost: 2, - health: 0, - spell_speed: SpellSpeed::Burst, - localized_spell_speed: "Burst".to_string(), - keywords: vec![ - CardKeyword::Burst, - ], - localized_keywords: vec![ - "Burst".to_string(), - ], - localized_description_xml: "Give an ally +2|+0 or +0|+3 this round.".to_string(), - localized_description_text: "Give an ally +2|+0 or +0|+3 this round.".to_string(), - localized_levelup_xml: "".to_string(), - localized_levelup_text: "".to_string(), - associated_card_codes: vec![], - associated_card_names_localized: vec![], - localized_flavor_text: r#""Never fear change. It will question you, test your limits. It is our greatest teacher." - Karma"#.to_string(), - artist_name: "SIXMOREVODKA".to_string(), - subtypes: vec![], - supertype: "".to_string(), - } - } - - fn expected_card_2() -> Card { - Card { - code: "01IO012T2".to_string(), - name: "Discipline of Fortitude".to_string(), - r#type: CardType::Spell, - set: CardSet::Foundations, - rarity: CardRarity::None, - collectible: false, - regions: vec![ - CardRegion::Ionia, - ], - localized_regions: vec![ - "Ionia".to_string(), - ], - art: vec![ - CardArt { - card_png: "http://dd.b.pvp.net/3_11_0/set1/en_us/img/cards/01IO012T2.png".to_string(), - full_png: "http://dd.b.pvp.net/3_11_0/set1/en_us/img/cards/01IO012T2-full.png".to_string(), - } - ], - attack: 0, - cost: 2, - health: 0, - spell_speed: SpellSpeed::Burst, - localized_spell_speed: "Burst".to_string(), - keywords: vec![ - CardKeyword::Burst, - ], - localized_keywords: vec![ - "Burst".to_string(), - ], - localized_description_xml: "Give an ally +0|+3 this round.".to_string(), - localized_description_text: "Give an ally +0|+3 this round.".to_string(), - localized_levelup_xml: "".to_string(), - localized_levelup_text: "".to_string(), - associated_card_codes: vec![], - associated_card_names_localized: vec![], - localized_flavor_text: "".to_string(), - artist_name: "SIXMOREVODKA".to_string(), - subtypes: vec![], - supertype: "".to_string(), - } - } - - fn expected_vec() -> Vec { - vec![expected_card_1(), expected_card_2()] - } - - fn expected_hashmap() -> HashMap { - let mut hm = HashMap::::new(); - hm.insert("01IO012".to_string(), expected_card_1()); - hm.insert("01IO012T2".to_string(), expected_card_2()); - hm - } - - #[test] - fn test_setjson_to_cardvec() { - assert_eq!( - setjson_to_cardvec(TEST_SETJSON.as_bytes()).unwrap(), - expected_vec() - ) - } - - #[test] - fn test_cardvec_to_cardhashmap() { - assert_eq!( - cardvec_to_cardhashmap(expected_vec()), - expected_hashmap() - ) - } -} \ No newline at end of file diff --git a/src/schema/corebundle/globals.rs b/src/schema/corebundle/globals.rs deleted file mode 100644 index 3072d57..0000000 --- a/src/schema/corebundle/globals.rs +++ /dev/null @@ -1,134 +0,0 @@ -use crate::schema::corebundle::CoreSet; - -use super::keyword::CoreKeyword; -use super::rarity::CoreRarity; -use super::region::CoreRegion; -use super::speed::CoreSpellSpeed; -use super::vocabterm::CoreVocabTerm; - -/// A complete `globals.json` file. -/// -/// It contains a list of all vocabulary terms, [CardKeyword]s, [CardRegion]s, [SpellSpeed]s, and [CardRarity]s present in the game. -#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] -pub struct CoreGlobals { - /// A [Vec] of all [CoreVocabTerm]s in the game. - #[serde(rename = "vocabTerms")] - pub vocab_terms: Vec, - - /// A [Vec] of all [CoreKeyword]s in the game. - pub keywords: Vec, - - /// A [Vec] of all [CoreRegion]s in the game. - pub regions: Vec, - - /// A [Vec] of all [CoreSpellSpeed]s in the game. - #[serde(rename = "spellSpeeds")] - pub spell_speeds: Vec, - - /// A [Vec] of all [CoreRarity]s in the game. - pub rarities: Vec, - - /// A [Vec] of all [CardSet]s in the game. - pub sets: Vec, -} - - -#[cfg(test)] -mod tests { - use crate::schema::corebundle::*; - use crate::schema::setbundle::*; - - #[test] - fn deserialize() { - assert_eq!( - serde_json::de::from_str::<'static, CoreGlobals>(r#" - { - "vocabTerms": [ - { - "description": "When you summon this, it gets its allegiance bonus if the top card of your deck matches its region.", - "name": "Allegiance", - "nameRef": "Allegiance" - } - ], - "keywords": [ - { - "description": "Inflicts damage beyond what would kill the target(s) to the enemy Nexus.", - "name": "Overwhelm", - "nameRef": "SpellOverwhelm" - } - ], - "regions": [ - { - "abbreviation": "NX", - "iconAbsolutePath": "http://dd.b.pvp.net/3_11_0/core/en_us/img/regions/icon-noxus.png", - "name": "Noxus", - "nameRef": "Noxus" - } - ], - "spellSpeeds": [ - { - "name": "Slow", - "nameRef": "Slow" - } - ], - "rarities": [ - { - "name": "COMMON", - "nameRef": "Common" - } - ], - "sets": [ - { - "iconAbsolutePath": "http://dd.b.pvp.net/3_11_0/core/en_us/img/sets/set3_crispmip.png", - "name": "Call of the Mountain", - "nameRef": "Set3" - } - ] - } - "#).unwrap(), - CoreGlobals { - vocab_terms: vec![ - CoreVocabTerm { - 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![ - CoreKeyword { - 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![ - CoreRegion { - 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![ - CoreSpellSpeed { - spell_speed: SpellSpeed::Slow, - name: "Slow".to_string(), - } - ], - rarities: vec![ - CoreRarity { - rarity: CardRarity::Common, - name: "COMMON".to_string(), - } - ], - sets: vec![ - CoreSet { - 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(), - } - ] - } - ) - } -} \ No newline at end of file diff --git a/src/schema/corebundle/mod.rs b/src/schema/corebundle/mod.rs deleted file mode 100644 index 4ba16fd..0000000 --- a/src/schema/corebundle/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! This module defines the types used in Data Dragon's [Core Bundle](https://developer.riotgames.com/docs/lor#data-dragon_core-bundles) `globals.json` files. - -pub use globals::CoreGlobals; -pub use keyword::CoreKeyword; -pub use rarity::CoreRarity; -pub use region::CoreRegion; -pub use set::CoreSet; -pub use speed::CoreSpellSpeed; -pub use vocabterm::CoreVocabTerm; - -mod globals; -mod vocabterm; -mod keyword; -mod region; -mod speed; -mod rarity; -mod set; - diff --git a/src/schema/setbundle/mod.rs b/src/schema/setbundle/mod.rs deleted file mode 100644 index f8346a5..0000000 --- a/src/schema/setbundle/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! This module defines the types used in Data Dragon's [Set Bundle](https://developer.riotgames.com/docs/lor#data-dragon_set-bundles) `set.json` files. - -pub use art::CardArt; -pub use card::Card; -pub use keyword::CardKeyword; -pub use r#type::CardType; -pub use rarity::CardRarity; -pub use region::CardRegion; -pub use set::CardSet; -pub use speed::SpellSpeed; - -mod card; -mod art; -mod r#type; -mod rarity; -mod region; -mod set; -mod speed; -mod keyword; - diff --git a/src/search/card.rs b/src/search/card.rs index ce91583..2deebdb 100644 --- a/src/search/card.rs +++ b/src/search/card.rs @@ -6,8 +6,9 @@ use tantivy::query::{QueryParser, QueryParserError}; use tantivy::schema::{Schema, TextOptions}; use tantivy::tokenizer::TextAnalyzer; use itertools::Itertools; -use crate::load::corebundle::MappedGlobals; -use crate::schema::setbundle::{Card, CardType}; +use crate::data::corebundle::CoreBundle; +use crate::data::setbundle::r#type::CardType; +use crate::data::setbundle::card::Card; /// Create a new [tantivy::tokenizer::TextAnalyzer] for card text. @@ -92,7 +93,7 @@ pub fn card_schema() -> Schema { /// Create a new [tantivy::Document] using a [Card] in a specific [locale](MappedGlobals] as base. -pub fn card_to_document(schema: &Schema, locale: &MappedGlobals, card: Card) -> Document { +pub fn card_to_document(schema: &Schema, cb: &CoreBundle, card: Card) -> Document { use tantivy::*; let f_code = schema.get_field("code").expect("schema to have a 'code' field"); @@ -129,17 +130,17 @@ pub fn card_to_document(schema: &Schema, locale: &MappedGlobals, card: Card) -> f_name => card.name, f_type => c_type, f_set => card.set - .localized(&locale.sets) + .localized(&cb.globals.sets) .map(|cs| cs.name.to_owned()) .unwrap_or_else(String::new), f_rarity => card.rarity - .localized(&locale.rarities) + .localized(&cb.globals.rarities) .map(|cr| cr.name.to_owned()) .unwrap_or_else(String::new), f_collectible => if card.collectible {1u64} else {0u64}, f_regions => card.regions.iter() .map(|region| region - .localized(&locale.regions) + .localized(&cb.globals.regions) .map(|cr| cr.name.to_owned()) .unwrap_or_else(String::new) ).join(" "), @@ -147,12 +148,12 @@ pub fn card_to_document(schema: &Schema, locale: &MappedGlobals, card: Card) -> f_cost => card.cost, f_health => card.health, f_spellspeed => card.spell_speed - .localized(&locale.spell_speeds) + .localized(&cb.globals.spell_speeds) .map(|ss| ss.name.to_owned()) .unwrap_or_else(String::new), f_keywords => card.keywords.iter() .map(|keyword| keyword - .localized(&locale.keywords) + .localized(&cb.globals.keywords) .map(|ck| ck.name.to_owned()) .unwrap_or_else(String::new)) .join(" "), diff --git a/src/telegram/bin.rs b/src/telegram/bin.rs deleted file mode 100644 index 224fe89..0000000 --- a/src/telegram/bin.rs +++ /dev/null @@ -1,7 +0,0 @@ -use log::*; - - -#[tokio::main] -async fn main() { - pretty_env_logger::init(); -} diff --git a/src/telegram/display.rs b/src/telegram/display.rs index 4cd849d..e5e357b 100644 --- a/src/telegram/display.rs +++ b/src/telegram/display.rs @@ -7,13 +7,10 @@ use std::collections::HashMap; use itertools::Itertools; use teloxide::utils::html::escape; -use crate::load::corebundle::MappedGlobals; -use crate::schema::corebundle::{CoreRegion, CoreSet}; -use crate::schema::setbundle::{Card, CardRegion, CardSet, CardType}; /// Render a [Card] to a [String] formatted with [Telegram Bot HTML](https://core.telegram.org/bots/api#html-style). -pub fn display_card(card: &Card, mg: &MappedGlobals) -> String { +pub fn display_card(card: &, mg: &MappedGlobals) -> String { let title = format!(r#"{}"#, &card.main_art().card_png, escape(&card.name)); let stats = match &card.r#type { diff --git a/src/telegram/mod.rs b/src/telegram/mod.rs index a874901..0a03374 100644 --- a/src/telegram/mod.rs +++ b/src/telegram/mod.rs @@ -1,2 +1 @@ pub(crate) mod display; -mod bin;