1
Fork 0
mirror of https://github.com/Steffo99/patched-porobot.git synced 2024-12-23 01:54:22 +00:00

Run cargo fmt

This commit is contained in:
Steffo 2022-09-03 19:15:44 +02:00
parent 54fc192b6e
commit 30a94754cd
Signed by: steffo
GPG key ID: 6965406171929D01
19 changed files with 232 additions and 155 deletions

View file

@ -1,7 +1,7 @@
//! Module defining structs representing localized card keywords. //! Module defining structs representing localized card keywords.
use std::collections::HashMap;
use crate::data::setbundle::keyword::CardKeyword; use crate::data::setbundle::keyword::CardKeyword;
use std::collections::HashMap;
/// A Legends of Runeterra [CardKeyword], and its associated localization. /// A Legends of Runeterra [CardKeyword], and its associated localization.
#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
@ -22,7 +22,6 @@ pub type LocalizedCardKeywordVec = Vec<LocalizedCardKeyword>;
/// An index of [LocalizedCardKeyword]s, with [LocalizedCardKeyword::keyword]s as keys. /// An index of [LocalizedCardKeyword]s, with [LocalizedCardKeyword::keyword]s as keys.
pub type LocalizedCardKeywordIndex = HashMap<CardKeyword, LocalizedCardKeyword>; pub type LocalizedCardKeywordIndex = HashMap<CardKeyword, LocalizedCardKeyword>;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -1,7 +1,7 @@
//! Module defining structs representing localized card rarities. //! Module defining structs representing localized card rarities.
use std::collections::HashMap;
use crate::data::setbundle::rarity::CardRarity; use crate::data::setbundle::rarity::CardRarity;
use std::collections::HashMap;
/// A Legends of Runeterra [CardRarity], and its associated localization. /// A Legends of Runeterra [CardRarity], and its associated localization.
#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
@ -19,7 +19,6 @@ pub type LocalizedCardRarityVec = Vec<LocalizedCardRarity>;
/// An index of [LocalizedCardRarity]s, with [LocalizedCardRarity::rarity]s as keys. /// An index of [LocalizedCardRarity]s, with [LocalizedCardRarity::rarity]s as keys.
pub type LocalizedCardRarityIndex = HashMap<CardRarity, LocalizedCardRarity>; pub type LocalizedCardRarityIndex = HashMap<CardRarity, LocalizedCardRarity>;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -1,7 +1,7 @@
//! Module defining structs representing localized card sets. //! Module defining structs representing localized card sets.
use std::collections::HashMap;
use crate::data::setbundle::set::CardSet; use crate::data::setbundle::set::CardSet;
use std::collections::HashMap;
/// A Legends of Runeterra [CardSet], and its associated localization. /// A Legends of Runeterra [CardSet], and its associated localization.
#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
@ -23,7 +23,6 @@ pub type LocalizedCardSetVec = Vec<LocalizedCardSet>;
/// An index of [LocalizedCardSet]s, with [LocalizedCardSet::set]s as keys. /// An index of [LocalizedCardSet]s, with [LocalizedCardSet::set]s as keys.
pub type LocalizedCardSetIndex = HashMap<CardSet, LocalizedCardSet>; pub type LocalizedCardSetIndex = HashMap<CardSet, LocalizedCardSet>;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -24,7 +24,6 @@ pub type LocalizedVocabTermVec = Vec<LocalizedVocabTerm>;
/// An index of [LocalizedVocabTerm]s, with [LocalizedVocabTerm::vocabterm]s as keys. /// An index of [LocalizedVocabTerm]s, with [LocalizedVocabTerm::vocabterm]s as keys.
pub type LocalizedVocabTermIndex = HashMap<String, LocalizedVocabTerm>; pub type LocalizedVocabTermIndex = HashMap<String, LocalizedVocabTerm>;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -1,15 +1,14 @@
//! Module defining the [`Deck`] struct and its serialization methods and results. //! Module defining the [`Deck`] struct and its serialization methods and results.
use std::collections::HashMap; use super::format::DeckCodeFormat;
use std::io::{Cursor, Read, Write};
use itertools::Itertools;
use varint_rs::{VarintReader, VarintWriter};
use crate::data::deckcode::version::{DeckCodeVersion, DeckCodeVersioned}; use crate::data::deckcode::version::{DeckCodeVersion, DeckCodeVersioned};
use crate::data::setbundle::code::CardCode; use crate::data::setbundle::code::CardCode;
use crate::data::setbundle::region::CardRegion; use crate::data::setbundle::region::CardRegion;
use crate::data::setbundle::set::CardSet; use crate::data::setbundle::set::CardSet;
use super::format::DeckCodeFormat; use itertools::Itertools;
use std::collections::HashMap;
use std::io::{Cursor, Read, Write};
use varint_rs::{VarintReader, VarintWriter};
/// A unshuffled Legends of Runeterra card deck. /// A unshuffled Legends of Runeterra card deck.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
@ -18,7 +17,6 @@ pub struct Deck {
pub contents: HashMap<CardCode, u32>, pub contents: HashMap<CardCode, u32>,
} }
impl Deck { impl Deck {
/// Decode a deck code into a [`Vec`] of [bytes](u8). /// Decode a deck code into a [`Vec`] of [bytes](u8).
fn decode_code(code: &str) -> DeckDecodingResult<Vec<u8>> { fn decode_code(code: &str) -> DeckDecodingResult<Vec<u8>> {
@ -29,23 +27,32 @@ impl Deck {
/// Encode a slice of [bytes](u8) into a deck code. /// Encode a slice of [bytes](u8) into a deck code.
fn encode_code(bytes: &[u8]) -> String { fn encode_code(bytes: &[u8]) -> String {
data_encoding::BASE32_NOPAD data_encoding::BASE32_NOPAD.encode(bytes)
.encode(bytes)
} }
/// [Read] the header byte into a [format](DeckCodeFormat) and [version](DeckCodeVersion) tuple. /// [Read] the header byte into a [format](DeckCodeFormat) and [version](DeckCodeVersion) tuple.
fn read_header<R: Read>(reader: &mut R) -> DeckDecodingResult<(DeckCodeFormat, DeckCodeVersion)> { fn read_header<R: Read>(
reader: &mut R,
) -> DeckDecodingResult<(DeckCodeFormat, DeckCodeVersion)> {
let mut format_version: [u8; 1] = [0; 1]; let mut format_version: [u8; 1] = [0; 1];
reader.read_exact(&mut format_version).map_err(DeckDecodingError::Read)?; reader
.read_exact(&mut format_version)
.map_err(DeckDecodingError::Read)?;
let format = DeckCodeFormat::try_from(format_version[0] >> 4).map_err(|_| DeckDecodingError::UnknownFormat)?; let format = DeckCodeFormat::try_from(format_version[0] >> 4)
let version = DeckCodeVersion::try_from(format_version[0] & 0xF).map_err(|_| DeckDecodingError::UnknownVersion)?; .map_err(|_| DeckDecodingError::UnknownFormat)?;
let version = DeckCodeVersion::try_from(format_version[0] & 0xF)
.map_err(|_| DeckDecodingError::UnknownVersion)?;
Ok((format, version)) Ok((format, version))
} }
/// [Write] the header byte with the given [format](DeckCodeFormat) and [version](DeckCodeVersion). /// [Write] the header byte with the given [format](DeckCodeFormat) and [version](DeckCodeVersion).
fn write_header<W: Write>(writer: &mut W, format: DeckCodeFormat, version: DeckCodeVersion) -> DeckEncodingResult<()> { fn write_header<W: Write>(
writer: &mut W,
format: DeckCodeFormat,
version: DeckCodeVersion,
) -> DeckEncodingResult<()> {
let format: u8 = format.into(); let format: u8 = format.into();
let version: u8 = version.into(); let version: u8 = version.into();
@ -103,7 +110,11 @@ impl Deck {
} }
/// [Read] the **groups** of a single supergroup. /// [Read] the **groups** of a single supergroup.
fn read_f1_supergroup<R: Read>(reader: &mut R, contents: &mut HashMap<CardCode, u32>, quantity: u32) -> DeckDecodingResult<()> { fn read_f1_supergroup<R: Read>(
reader: &mut R,
contents: &mut HashMap<CardCode, u32>,
quantity: u32,
) -> DeckDecodingResult<()> {
// Read the number of groups in the supergroup // Read the number of groups in the supergroup
let len = reader.read_u32_varint().map_err(DeckDecodingError::Read)?; let len = reader.read_u32_varint().map_err(DeckDecodingError::Read)?;
@ -116,7 +127,9 @@ impl Deck {
} }
/// Given a slice of [`CardCode`]s, group them by set and region. /// Given a slice of [`CardCode`]s, group them by set and region.
fn f1_group_cards<'cc>(codes: &[&'cc CardCode]) -> HashMap<(&'cc str, &'cc str), Vec<&'cc CardCode>> { fn f1_group_cards<'cc>(
codes: &[&'cc CardCode],
) -> HashMap<(&'cc str, &'cc str), Vec<&'cc CardCode>> {
// Create the hashmap accumulating groups of cards // Create the hashmap accumulating groups of cards
// It has the tuple (set, region) as key // It has the tuple (set, region) as key
let mut groups = HashMap::new(); let mut groups = HashMap::new();
@ -145,22 +158,28 @@ impl Deck {
} }
/// [Write] the **groups** of a single supergroup. /// [Write] the **groups** of a single supergroup.
fn write_f1_supergroup<W: Write>(writer: &mut W, supergroup: &[&CardCode]) -> DeckEncodingResult<()> { fn write_f1_supergroup<W: Write>(
writer: &mut W,
supergroup: &[&CardCode],
) -> DeckEncodingResult<()> {
// Arrange cards into groups // Arrange cards into groups
let groups = Self::f1_group_cards(supergroup); let groups = Self::f1_group_cards(supergroup);
// Determine the number of groups in the supergroup // Determine the number of groups in the supergroup
let len: u32 = groups.len().try_into().expect("groups length to be smaller than usize"); let len: u32 = groups
writer.write_u32_varint(len).map_err(DeckEncodingError::Write)?; .len()
.try_into()
.expect("groups length to be smaller than usize");
writer
.write_u32_varint(len)
.map_err(DeckEncodingError::Write)?;
// Sort first by ascending group length, then by key // Sort first by ascending group length, then by key
let groups = groups let groups = groups
.into_iter() .into_iter()
.sorted_by(|(a_key, a_group), (b_key, b_group)| .sorted_by(|(a_key, a_group), (b_key, b_group)| {
a_group.len().cmp(&b_group.len()) a_group.len().cmp(&b_group.len()).then(a_key.cmp(b_key))
.then( });
a_key.cmp(b_key))
);
// Write all groups // Write all groups
for ((set, region), group) in groups { for ((set, region), group) in groups {
@ -171,14 +190,22 @@ impl Deck {
} }
/// [Read] the **cards** of a single group. /// [Read] the **cards** of a single group.
fn read_f1_group<R: Read>(reader: &mut R, contents: &mut HashMap<CardCode, u32>, quantity: u32) -> DeckDecodingResult<()> { fn read_f1_group<R: Read>(
reader: &mut R,
contents: &mut HashMap<CardCode, u32>,
quantity: u32,
) -> DeckDecodingResult<()> {
let card_count = reader.read_u32_varint().map_err(DeckDecodingError::Read)?; let card_count = reader.read_u32_varint().map_err(DeckDecodingError::Read)?;
let set = reader.read_u32_varint().map_err(DeckDecodingError::Read)?; let set = reader.read_u32_varint().map_err(DeckDecodingError::Read)?;
let set = CardSet::from(set).to_code().ok_or(DeckDecodingError::UnknownSet)?; let set = CardSet::from(set)
.to_code()
.ok_or(DeckDecodingError::UnknownSet)?;
let region = reader.read_u32_varint().map_err(DeckDecodingError::Read)?; let region = reader.read_u32_varint().map_err(DeckDecodingError::Read)?;
let region = CardRegion::from(region).to_code().ok_or(DeckDecodingError::UnknownRegion)?; let region = CardRegion::from(region)
.to_code()
.ok_or(DeckDecodingError::UnknownRegion)?;
for _card in 0..card_count { for _card in 0..card_count {
Self::read_f1_standard_card(reader, contents, quantity, &set, &region)?; Self::read_f1_standard_card(reader, contents, quantity, &set, &region)?;
@ -188,15 +215,33 @@ impl Deck {
} }
/// [Write] the **cards** of a single group. /// [Write] the **cards** of a single group.
fn write_f1_group<W: Write>(writer: &mut W, group: &[&CardCode], set: &str, region: &str) -> DeckEncodingResult<()> { fn write_f1_group<W: Write>(
let len: u32 = group.len().try_into().expect("cards length to be smaller than usize"); writer: &mut W,
writer.write_u32_varint(len).map_err(DeckEncodingError::Write)?; group: &[&CardCode],
set: &str,
region: &str,
) -> DeckEncodingResult<()> {
let len: u32 = group
.len()
.try_into()
.expect("cards length to be smaller than usize");
writer
.write_u32_varint(len)
.map_err(DeckEncodingError::Write)?;
let set: u32 = CardSet::from_code(set).try_into().map_err(|_| DeckEncodingError::UnknownSet)?; let set: u32 = CardSet::from_code(set)
writer.write_u32_varint(set).map_err(DeckEncodingError::Write)?; .try_into()
.map_err(|_| DeckEncodingError::UnknownSet)?;
writer
.write_u32_varint(set)
.map_err(DeckEncodingError::Write)?;
let region: u32 = CardRegion::from_code(region).try_into().map_err(|_| DeckEncodingError::UnknownRegion)?; let region: u32 = CardRegion::from_code(region)
writer.write_u32_varint(region).map_err(DeckEncodingError::Write)?; .try_into()
.map_err(|_| DeckEncodingError::UnknownRegion)?;
writer
.write_u32_varint(region)
.map_err(DeckEncodingError::Write)?;
for card in group.iter().sorted() { for card in group.iter().sorted() {
Self::write_f1_standard_card(writer, card.card())?; Self::write_f1_standard_card(writer, card.card())?;
@ -206,7 +251,13 @@ impl Deck {
} }
/// [Read] **a single card**. /// [Read] **a single card**.
fn read_f1_standard_card<R: Read>(reader: &mut R, contents: &mut HashMap<CardCode, u32>, quantity: u32, set: &str, region: &str) -> DeckDecodingResult<()> { fn read_f1_standard_card<R: Read>(
reader: &mut R,
contents: &mut HashMap<CardCode, u32>,
quantity: u32,
set: &str,
region: &str,
) -> DeckDecodingResult<()> {
let card = reader.read_u32_varint().map_err(DeckDecodingError::Read)?; let card = reader.read_u32_varint().map_err(DeckDecodingError::Read)?;
let code = CardCode::from_s_r_c(set, region, card); let code = CardCode::from_s_r_c(set, region, card);
@ -217,15 +268,21 @@ impl Deck {
/// [Write] **a single card**. /// [Write] **a single card**.
fn write_f1_standard_card<W: Write>(writer: &mut W, card: &str) -> DeckEncodingResult<()> { fn write_f1_standard_card<W: Write>(writer: &mut W, card: &str) -> DeckEncodingResult<()> {
let card = card.parse::<u32>().map_err(DeckEncodingError::InvalidCardNumber)?; let card = card
writer.write_u32_varint(card).map_err(DeckEncodingError::Write)?; .parse::<u32>()
.map_err(DeckEncodingError::InvalidCardNumber)?;
writer
.write_u32_varint(card)
.map_err(DeckEncodingError::Write)?;
Ok(()) Ok(())
} }
/// [Read] the **extra segment** of the deck code. /// [Read] the **extra segment** of the deck code.
fn read_f1_extra<R: Read>(reader: &mut R, contents: &mut HashMap<CardCode, u32>) -> DeckDecodingResult<()> { fn read_f1_extra<R: Read>(
reader: &mut R,
contents: &mut HashMap<CardCode, u32>,
) -> DeckDecodingResult<()> {
// While the cursor has still some bytes left... // While the cursor has still some bytes left...
while Self::read_f1_extra_card(reader, contents).is_ok() {} while Self::read_f1_extra_card(reader, contents).is_ok() {}
@ -233,7 +290,10 @@ impl Deck {
} }
/// [Write] the **extra segment** of the deck code. /// [Write] the **extra segment** of the deck code.
fn write_f1_extra<W: Write>(writer: &mut W, codes: Vec<(&CardCode, u32)>) -> DeckEncodingResult<()> { fn write_f1_extra<W: Write>(
writer: &mut W,
codes: Vec<(&CardCode, u32)>,
) -> DeckEncodingResult<()> {
for (code, quantity) in codes.iter().sorted() { for (code, quantity) in codes.iter().sorted() {
Self::write_f1_extra_card(writer, code, *quantity)?; Self::write_f1_extra_card(writer, code, *quantity)?;
} }
@ -242,14 +302,21 @@ impl Deck {
} }
/// [Read] **a single card** with a **non-standard quantity**. /// [Read] **a single card** with a **non-standard quantity**.
fn read_f1_extra_card<R: Read>(reader: &mut R, contents: &mut HashMap<CardCode, u32>) -> DeckDecodingResult<()> { fn read_f1_extra_card<R: Read>(
reader: &mut R,
contents: &mut HashMap<CardCode, u32>,
) -> DeckDecodingResult<()> {
let quantity = reader.read_u32_varint().map_err(DeckDecodingError::Read)?; let quantity = reader.read_u32_varint().map_err(DeckDecodingError::Read)?;
let set = reader.read_u32_varint().map_err(DeckDecodingError::Read)?; let set = reader.read_u32_varint().map_err(DeckDecodingError::Read)?;
let set = CardSet::from(set).to_code().ok_or(DeckDecodingError::UnknownSet)?; let set = CardSet::from(set)
.to_code()
.ok_or(DeckDecodingError::UnknownSet)?;
let region = reader.read_u32_varint().map_err(DeckDecodingError::Read)?; let region = reader.read_u32_varint().map_err(DeckDecodingError::Read)?;
let region = CardRegion::from(region).to_code().ok_or(DeckDecodingError::UnknownRegion)?; let region = CardRegion::from(region)
.to_code()
.ok_or(DeckDecodingError::UnknownRegion)?;
let card = reader.read_u32_varint().map_err(DeckDecodingError::Read)?; let card = reader.read_u32_varint().map_err(DeckDecodingError::Read)?;
@ -260,19 +327,36 @@ impl Deck {
} }
/// [Write] **a single card** with a **non-standard quantity**. /// [Write] **a single card** with a **non-standard quantity**.
fn write_f1_extra_card<W: Write>(writer: &mut W, code: &CardCode, quantity: u32) -> DeckEncodingResult<()> { fn write_f1_extra_card<W: Write>(
writer.write_u32_varint(quantity).map_err(DeckEncodingError::Write)?; writer: &mut W,
code: &CardCode,
quantity: u32,
) -> DeckEncodingResult<()> {
writer
.write_u32_varint(quantity)
.map_err(DeckEncodingError::Write)?;
let set = CardSet::from_code(code.set()); let set = CardSet::from_code(code.set());
let set: u32 = set.try_into().map_err(|_| DeckEncodingError::UnknownSet)?; let set: u32 = set.try_into().map_err(|_| DeckEncodingError::UnknownSet)?;
writer.write_u32_varint(set).map_err(DeckEncodingError::Write)?; writer
.write_u32_varint(set)
.map_err(DeckEncodingError::Write)?;
let region = CardRegion::from_code(code.region()); let region = CardRegion::from_code(code.region());
let region: u32 = region.try_into().map_err(|_| DeckEncodingError::UnknownRegion)?; let region: u32 = region
writer.write_u32_varint(region).map_err(DeckEncodingError::Write)?; .try_into()
.map_err(|_| DeckEncodingError::UnknownRegion)?;
writer
.write_u32_varint(region)
.map_err(DeckEncodingError::Write)?;
let card = code.card().parse::<u32>().map_err(DeckEncodingError::InvalidCardNumber)?; let card = code
writer.write_u32_varint(card).map_err(DeckEncodingError::Write)?; .card()
.parse::<u32>()
.map_err(DeckEncodingError::InvalidCardNumber)?;
writer
.write_u32_varint(card)
.map_err(DeckEncodingError::Write)?;
Ok(()) Ok(())
} }
@ -293,7 +377,7 @@ impl Deck {
let (format, _version) = Self::read_header(&mut cursor)?; let (format, _version) = Self::read_header(&mut cursor)?;
match format { match format {
DeckCodeFormat::F1 => Self::read_f1_body(&mut cursor) DeckCodeFormat::F1 => Self::read_f1_body(&mut cursor),
} }
} }
@ -315,7 +399,9 @@ impl Deck {
pub fn to_code(&self, format: DeckCodeFormat) -> DeckEncodingResult<String> { pub fn to_code(&self, format: DeckCodeFormat) -> DeckEncodingResult<String> {
let mut cursor = Cursor::new(Vec::new()); let mut cursor = Cursor::new(Vec::new());
let version = self.min_deckcode_version().ok_or(DeckEncodingError::UnknownVersion)?; let version = self
.min_deckcode_version()
.ok_or(DeckEncodingError::UnknownVersion)?;
Self::write_header(&mut cursor, format, version)?; Self::write_header(&mut cursor, format, version)?;
@ -327,7 +413,6 @@ impl Deck {
} }
} }
/// An error occoured while decoding a [`Deck`] from a code. /// An error occoured while decoding a [`Deck`] from a code.
#[derive(Debug)] #[derive(Debug)]
pub enum DeckDecodingError { pub enum DeckDecodingError {
@ -366,7 +451,6 @@ pub type DeckDecodingResult<T> = Result<T, DeckDecodingError>;
/// The [`Result`] of a [`Deck`] **encoding** operation, for example [`Deck::to_code`]. /// The [`Result`] of a [`Deck`] **encoding** operation, for example [`Deck::to_code`].
pub type DeckEncodingResult<T> = Result<T, DeckEncodingError>; pub type DeckEncodingResult<T> = Result<T, DeckEncodingError>;
/// Macro to build a deck from card code strings and quantities. /// Macro to build a deck from card code strings and quantities.
/// ///
/// # Example /// # Example
@ -408,7 +492,7 @@ macro_rules! deck {
} }
} }
#[rustfmt::skip::macros(test_de_ser, test_ser_de)]
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -457,12 +541,14 @@ mod tests {
fn $id() { fn $id() {
use patched_porobot::data::deckcode::deck::Deck; use patched_porobot::data::deckcode::deck::Deck;
let deck1 = $deck; let deck1 = $deck;
let code = deck1.to_code(DeckCodeFormat::F1).expect("deck to serialize successfully"); let code = deck1
.to_code(DeckCodeFormat::F1)
.expect("deck to serialize successfully");
println!("Serialized deck code (for science, obviously): {}", &code); println!("Serialized deck code (for science, obviously): {}", &code);
let deck2 = Deck::from_code(&code).expect("deck to deserialize successfully"); let deck2 = Deck::from_code(&code).expect("deck to deserialize successfully");
assert_eq!(deck1, deck2); assert_eq!(deck1, deck2);
} }
} };
} }
// Some tests from https://github.com/RiotGames/LoRDeckCodes/blob/main/LoRDeckCodes_Tests/UnitTest1.cs // Some tests from https://github.com/RiotGames/LoRDeckCodes/blob/main/LoRDeckCodes_Tests/UnitTest1.cs
@ -571,5 +657,4 @@ mod tests {
]); ]);
//test_ser_de!(test_ser_de_, deck![]); //test_ser_de!(test_ser_de_, deck![]);
} }

View file

@ -1,6 +1,5 @@
//! Module defining [`DeckCodeFormat`]. //! Module defining [`DeckCodeFormat`].
/// The format of a deck code. /// The format of a deck code.
#[non_exhaustive] #[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -9,14 +8,13 @@ pub enum DeckCodeFormat {
F1, F1,
} }
impl TryFrom<u8> for DeckCodeFormat { impl TryFrom<u8> for DeckCodeFormat {
type Error = (); type Error = ();
fn try_from(value: u8) -> Result<Self, Self::Error> { fn try_from(value: u8) -> Result<Self, Self::Error> {
match value { match value {
1 => Ok(Self::F1), 1 => Ok(Self::F1),
_ => Err(()) _ => Err(()),
} }
} }
} }

View file

@ -3,5 +3,5 @@
//! Adapted from [RiotGames/LoRDeckCodes](https://github.com/RiotGames/LoRDeckCodes) and from [iulianR/lordeckcodes-rs](https://github.com/iulianR/lordeckcodes-rs). //! Adapted from [RiotGames/LoRDeckCodes](https://github.com/RiotGames/LoRDeckCodes) and from [iulianR/lordeckcodes-rs](https://github.com/iulianR/lordeckcodes-rs).
pub mod deck; pub mod deck;
pub mod version;
pub mod format; pub mod format;
pub mod version;

View file

@ -4,7 +4,6 @@ use crate::data::deckcode::deck::Deck;
use crate::data::setbundle::code::CardCode; use crate::data::setbundle::code::CardCode;
use crate::data::setbundle::region::CardRegion; use crate::data::setbundle::region::CardRegion;
/// The version of a deck code. /// The version of a deck code.
#[non_exhaustive] #[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -27,7 +26,6 @@ pub enum DeckCodeVersion {
V5, V5,
} }
impl TryFrom<u8> for DeckCodeVersion { impl TryFrom<u8> for DeckCodeVersion {
type Error = (); type Error = ();
@ -38,7 +36,7 @@ impl TryFrom<u8> for DeckCodeVersion {
3 => Ok(Self::V3), 3 => Ok(Self::V3),
4 => Ok(Self::V4), 4 => Ok(Self::V4),
5 => Ok(Self::V5), 5 => Ok(Self::V5),
_ => Err(()) _ => Err(()),
} }
} }
} }
@ -55,15 +53,12 @@ impl From<DeckCodeVersion> for u8 {
} }
} }
/// Indicates that a given type is versioned in the [specs for deck codes](https://github.com/RiotGames/LoRDeckCodes). /// Indicates that a given type is versioned in the [specs for deck codes](https://github.com/RiotGames/LoRDeckCodes).
pub trait DeckCodeVersioned { pub trait DeckCodeVersioned {
/// Get the minimum deck version required to encode the deck in "code" format. /// Get the minimum deck version required to encode the deck in "code" format.
fn min_deckcode_version(&self) -> Option<DeckCodeVersion>; fn min_deckcode_version(&self) -> Option<DeckCodeVersion>;
} }
impl DeckCodeVersioned for CardRegion { impl DeckCodeVersioned for CardRegion {
fn min_deckcode_version(&self) -> Option<DeckCodeVersion> { fn min_deckcode_version(&self) -> Option<DeckCodeVersion> {
match self { match self {
@ -91,7 +86,6 @@ impl DeckCodeVersioned for CardRegion {
} }
} }
/// [`CardCode`]'s version is the maximum version of its components. /// [`CardCode`]'s version is the maximum version of its components.
impl DeckCodeVersioned for CardCode { impl DeckCodeVersioned for CardCode {
fn min_deckcode_version(&self) -> Option<DeckCodeVersion> { fn min_deckcode_version(&self) -> Option<DeckCodeVersion> {
@ -99,7 +93,6 @@ impl DeckCodeVersioned for CardCode {
} }
} }
/// [`Deck`]'s version is the maximum version of all its [`CardCode`]s. /// [`Deck`]'s version is the maximum version of all its [`CardCode`]s.
impl DeckCodeVersioned for Deck { impl DeckCodeVersioned for Deck {
fn min_deckcode_version(&self) -> Option<DeckCodeVersion> { fn min_deckcode_version(&self) -> Option<DeckCodeVersion> {

View file

@ -4,5 +4,5 @@
pub mod anybundle; pub mod anybundle;
pub mod corebundle; pub mod corebundle;
pub mod setbundle;
pub mod deckcode; pub mod deckcode;
pub mod setbundle;

View file

@ -1,17 +1,17 @@
//! Module defining [Card]. //! Module defining [Card].
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use crate::data::setbundle::subtype::CardSubtype;
use crate::data::setbundle::supertype::CardSupertype;
use super::r#type::CardType;
use super::art::CardArt; use super::art::CardArt;
use super::code::CardCode;
use super::keyword::CardKeyword; use super::keyword::CardKeyword;
use super::r#type::CardType;
use super::rarity::CardRarity; use super::rarity::CardRarity;
use super::region::CardRegion; use super::region::CardRegion;
use super::speed::SpellSpeed;
use super::set::CardSet; use super::set::CardSet;
use super::code::CardCode; use super::speed::SpellSpeed;
use crate::data::setbundle::subtype::CardSubtype;
use crate::data::setbundle::supertype::CardSupertype;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
/// A single Legends of Runeterra card, as represented in a `set*.json` file. /// A single Legends of Runeterra card, as represented in a `set*.json` file.
/// ///
@ -146,10 +146,12 @@ pub struct Card {
pub supertype: CardSupertype, pub supertype: CardSupertype,
} }
impl Card { impl Card {
/// Get references to the cards associated with this one, given an [HashMap] of cards indexed by code. /// 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, index: &'hm CardIndex) -> impl Iterator<Item=Option<&'hm Card>> + 'c { pub fn associated_cards<'c, 'hm: 'c>(
&'c self,
index: &'hm CardIndex,
) -> impl Iterator<Item = Option<&'hm Card>> + 'c {
self.associated_card_codes.iter().map(|r| index.get(r)) self.associated_card_codes.iter().map(|r| index.get(r))
} }
@ -161,7 +163,6 @@ impl Card {
} }
} }
/// Two [`Card`]s are equal if they have the same [`Card::code`]. /// Two [`Card`]s are equal if they have the same [`Card::code`].
impl PartialEq for Card { impl PartialEq for Card {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
@ -169,7 +170,6 @@ impl PartialEq for Card {
} }
} }
/// [`Card`] [`Hash`]es are equal to hashes of their [`Card::code`]. /// [`Card`] [`Hash`]es are equal to hashes of their [`Card::code`].
impl Hash for Card { impl Hash for Card {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
@ -177,11 +177,9 @@ impl Hash for Card {
} }
} }
/// An index of [Card]s, with [CardCode]s as keys. /// An index of [Card]s, with [CardCode]s as keys.
pub type CardIndex = HashMap<CardCode, Card>; pub type CardIndex = HashMap<CardCode, Card>;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -1,6 +1,5 @@
//! Module defining [CardCode]. //! Module defining [CardCode].
use crate::data::setbundle::card::{Card, CardIndex}; use crate::data::setbundle::card::{Card, CardIndex};
/// The internal code of a [Card](super::card::Card). /// The internal code of a [Card](super::card::Card).
@ -22,14 +21,15 @@ use crate::data::setbundle::card::{Card, CardIndex};
/// # Warning /// # Warning
/// ///
/// The way this is built is pretty... unsafe, so beware to not construct this with invalid codes. /// The way this is built is pretty... unsafe, so beware to not construct this with invalid codes.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize)] #[derive(
Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
)]
#[serde(transparent)] #[serde(transparent)]
pub struct CardCode { pub struct CardCode {
/// The card code as a [`String`]. /// The card code as a [`String`].
pub full: String pub full: String,
} }
impl CardCode { impl CardCode {
/// Determines whether the card code is valid or not by checking the following: /// Determines whether the card code is valid or not by checking the following:
/// ///

View file

@ -10,6 +10,7 @@ use std::path::Path;
pub mod art; pub mod art;
pub mod card; pub mod card;
pub mod code;
pub mod keyword; pub mod keyword;
pub mod rarity; pub mod rarity;
pub mod region; pub mod region;
@ -18,7 +19,6 @@ pub mod speed;
pub mod subtype; pub mod subtype;
pub mod supertype; pub mod supertype;
pub mod r#type; pub mod r#type;
pub mod code;
/// A parsed [Data Dragon] [Set Bundle]. /// A parsed [Data Dragon] [Set Bundle].
/// ///

View file

@ -50,7 +50,10 @@ impl CardRegion {
/// Returns [Option::None] if no matching [LocalizedCardRegion] was found, for example for [CardRegion::Unsupported] regions. /// Returns [Option::None] if no matching [LocalizedCardRegion] was found, for example for [CardRegion::Unsupported] regions.
/// ///
/// Equivalent to calling [LocalizedCardRegionIndex::get]. /// Equivalent to calling [LocalizedCardRegionIndex::get].
pub fn localized<'hm>(&self, hm: &'hm LocalizedCardRegionIndex) -> Option<&'hm LocalizedCardRegion> { pub fn localized<'hm>(
&self,
hm: &'hm LocalizedCardRegionIndex,
) -> Option<&'hm LocalizedCardRegion> {
hm.get(self) hm.get(self)
} }
@ -141,7 +144,6 @@ impl TryFrom<CardRegion> for u32 {
} }
} }
#[cfg(test)] #[cfg(test)]
#[rustfmt::skip] #[rustfmt::skip]
mod tests { mod tests {

View file

@ -86,7 +86,6 @@ impl CardSet {
} }
} }
/// Get the [`CardSet`] from its internal id. /// Get the [`CardSet`] from its internal id.
/// ///
/// [`CardSet::Events`] cards have the id of the set they were released in, so it is impossible to determine if a card belongs to that set from its id. /// [`CardSet::Events`] cards have the id of the set they were released in, so it is impossible to determine if a card belongs to that set from its id.
@ -123,7 +122,6 @@ impl TryFrom<CardSet> for u32 {
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::CardSet; use super::CardSet;

View file

@ -2,13 +2,13 @@
use crate::data::corebundle::globals::LocalizedGlobalsIndexes; use crate::data::corebundle::globals::LocalizedGlobalsIndexes;
use crate::data::setbundle::card::{Card, CardIndex}; use crate::data::setbundle::card::{Card, CardIndex};
use crate::data::setbundle::code::CardCode;
use itertools::Itertools; use itertools::Itertools;
use tantivy::collector::TopDocs; use tantivy::collector::TopDocs;
use tantivy::query::{QueryParser, QueryParserError}; use tantivy::query::{QueryParser, QueryParserError};
use tantivy::schema::{Field, NumericOptions, Schema, TextOptions}; use tantivy::schema::{Field, NumericOptions, Schema, TextOptions};
use tantivy::tokenizer::TextAnalyzer; use tantivy::tokenizer::TextAnalyzer;
use tantivy::{Document, Index, IndexReader, IndexWriter}; use tantivy::{Document, Index, IndexReader, IndexWriter};
use crate::data::setbundle::code::CardCode;
/// The search engine. /// The search engine.
/// ///

View file

@ -6,6 +6,7 @@ use crate::data::corebundle::globals::LocalizedGlobalsIndexes;
use crate::data::corebundle::keyword::LocalizedCardKeywordIndex; use crate::data::corebundle::keyword::LocalizedCardKeywordIndex;
use crate::data::corebundle::region::LocalizedCardRegionIndex; use crate::data::corebundle::region::LocalizedCardRegionIndex;
use crate::data::corebundle::set::LocalizedCardSetIndex; use crate::data::corebundle::set::LocalizedCardSetIndex;
use crate::data::deckcode::deck::Deck;
use crate::data::setbundle::card::{Card, CardIndex}; use crate::data::setbundle::card::{Card, CardIndex};
use crate::data::setbundle::keyword::CardKeyword; use crate::data::setbundle::keyword::CardKeyword;
use crate::data::setbundle::r#type::CardType; use crate::data::setbundle::r#type::CardType;
@ -13,7 +14,6 @@ use crate::data::setbundle::region::CardRegion;
use crate::data::setbundle::set::CardSet; use crate::data::setbundle::set::CardSet;
use crate::data::setbundle::subtype::CardSubtype; use crate::data::setbundle::subtype::CardSubtype;
use crate::data::setbundle::supertype::CardSupertype; use crate::data::setbundle::supertype::CardSupertype;
use crate::data::deckcode::deck::Deck;
use itertools::Itertools; use itertools::Itertools;
use teloxide::utils::html::escape; use teloxide::utils::html::escape;
@ -158,13 +158,17 @@ fn display_levelup(levelup: &String) -> String {
/// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style /// [Telegram Bot HTML]: https://core.telegram.org/bots/api#html-style
pub fn display_deck(index: &CardIndex, deck: &Deck, code: String) -> String { pub fn display_deck(index: &CardIndex, deck: &Deck, code: String) -> String {
// TODO: optimize this // TODO: optimize this
let cards = deck.contents let cards = deck
.contents
.keys() .keys()
.sorted_by(|a, b| { .sorted_by(|a, b| {
let card_a = index.get(a).expect("card to exist in the index"); let card_a = index.get(a).expect("card to exist in the index");
let card_b = index.get(b).expect("card to exist in the index"); let card_b = index.get(b).expect("card to exist in the index");
card_a.cost.cmp(&card_b.cost).then(card_a.name.cmp(&card_b.name)) card_a
.cost
.cmp(&card_b.cost)
.then(card_a.name.cmp(&card_b.name))
}) })
.map(|k| { .map(|k| {
let card = index.get(k).expect("card to exist in the index"); let card = index.get(k).expect("card to exist in the index");
@ -172,8 +176,7 @@ pub fn display_deck(index: &CardIndex, deck: &Deck, code: String) -> String {
if card.supertype == "Champion" { if card.supertype == "Champion" {
format!("<b>{}×</b> <u>{}</u>", &quantity, &card.name) format!("<b>{}×</b> <u>{}</u>", &quantity, &card.name)
} } else {
else {
format!("<b>{}×</b> {}", &quantity, &card.name) format!("<b>{}×</b> {}", &quantity, &card.name)
} }
}) })

View file

@ -1,5 +1,6 @@
//! Module providing handlers for @patchedporobot on Telegram. //! Module providing handlers for @patchedporobot on Telegram.
use crate::data::deckcode::deck::Deck;
use crate::search::cardsearch::CardSearchEngine; use crate::search::cardsearch::CardSearchEngine;
use crate::telegram::inline::{card_to_inlinequeryresult, deck_to_inlinequeryresult}; use crate::telegram::inline::{card_to_inlinequeryresult, deck_to_inlinequeryresult};
use itertools::Itertools; use itertools::Itertools;
@ -9,7 +10,6 @@ use teloxide::payloads::{AnswerInlineQuery, SendMessage};
use teloxide::prelude::*; use teloxide::prelude::*;
use teloxide::requests::{JsonRequest, ResponseResult}; use teloxide::requests::{JsonRequest, ResponseResult};
use teloxide::types::{ParseMode, Recipient}; use teloxide::types::{ParseMode, Recipient};
use crate::data::deckcode::deck::Deck;
/// Handle inline queries by searching cards on the [CardSearchEngine]. /// Handle inline queries by searching cards on the [CardSearchEngine].
pub fn inline_query_handler( pub fn inline_query_handler(
@ -37,15 +37,13 @@ pub fn inline_query_handler(
debug!("Parsed deck successfully!"); debug!("Parsed deck successfully!");
break AnswerInlineQuery { break AnswerInlineQuery {
inline_query_id: query.id.clone(), inline_query_id: query.id.clone(),
results: vec![ results: vec![deck_to_inlinequeryresult(&engine.cards, &deck)],
deck_to_inlinequeryresult(&engine.cards, &deck)
],
cache_time: None, cache_time: None,
is_personal: Some(false), is_personal: Some(false),
next_offset: None, next_offset: None,
switch_pm_text: None, switch_pm_text: None,
switch_pm_parameter: None, switch_pm_parameter: None,
} };
} }
debug!("Querying the card search engine..."); debug!("Querying the card search engine...");

View file

@ -2,15 +2,18 @@
//! //!
//! [inline mode]: https://core.telegram.org/bots/api#inline-mode //! [inline mode]: https://core.telegram.org/bots/api#inline-mode
use crate::data::corebundle::globals::LocalizedGlobalsIndexes;
use crate::data::deckcode::deck::Deck;
use crate::data::deckcode::format::DeckCodeFormat;
use crate::data::setbundle::card::{Card, CardIndex};
use crate::telegram::display::{display_card, display_deck};
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::hash::Hash; use std::hash::Hash;
use std::ptr::hash; use std::ptr::hash;
use crate::data::corebundle::globals::LocalizedGlobalsIndexes; use teloxide::types::{
use crate::data::setbundle::card::{Card, CardIndex}; InlineQueryResult, InlineQueryResultArticle, InlineQueryResultPhoto, InputMessageContent,
use crate::telegram::display::{display_card, display_deck}; InputMessageContentText, ParseMode,
use teloxide::types::{InlineQueryResult, InlineQueryResultArticle, InlineQueryResultPhoto, InputMessageContent, InputMessageContentText, ParseMode}; };
use crate::data::deckcode::deck::Deck;
use crate::data::deckcode::format::DeckCodeFormat;
/// Converts a [Card] into a [InlineQueryResult]. /// Converts a [Card] into a [InlineQueryResult].
pub fn card_to_inlinequeryresult( pub fn card_to_inlinequeryresult(
@ -43,9 +46,10 @@ pub fn card_to_inlinequeryresult(
}) })
} }
pub fn deck_to_inlinequeryresult(index: &CardIndex, deck: &Deck) -> InlineQueryResult { pub fn deck_to_inlinequeryresult(index: &CardIndex, deck: &Deck) -> InlineQueryResult {
let code = deck.to_code(DeckCodeFormat::F1).expect("serialized deck to deserialize properly"); let code = deck
.to_code(DeckCodeFormat::F1)
.expect("serialized deck to deserialize properly");
InlineQueryResult::Article(InlineQueryResultArticle { InlineQueryResult::Article(InlineQueryResultArticle {
id: format!("{:x}", md5::compute(&code)), id: format!("{:x}", md5::compute(&code)),
@ -54,7 +58,7 @@ pub fn deck_to_inlinequeryresult(index: &CardIndex, deck: &Deck) -> InlineQueryR
message_text: display_deck(index, deck, code), message_text: display_deck(index, deck, code),
parse_mode: Some(ParseMode::Html), parse_mode: Some(ParseMode::Html),
entities: None, entities: None,
disable_web_page_preview: Some(true) disable_web_page_preview: Some(true),
}), }),
reply_markup: None, reply_markup: None,
url: None, url: None,
@ -62,6 +66,6 @@ pub fn deck_to_inlinequeryresult(index: &CardIndex, deck: &Deck) -> InlineQueryR
description: None, description: None,
thumb_url: None, thumb_url: None,
thumb_width: None, thumb_width: None,
thumb_height: None thumb_height: None,
}) })
} }

View file

@ -30,8 +30,10 @@ pub async fn main() {
let mut cards: Vec<Card> = vec![]; let mut cards: Vec<Card> = vec![];
for setpath in setpaths { for setpath in setpaths {
debug!("Loading {:?}...", &setpath); debug!("Loading {:?}...", &setpath);
let set = SetBundle::load(&setpath) let set = SetBundle::load(&setpath).expect(&*format!(
.expect(&*format!("to be able to load {:?} as a set bundle", &setpath)); "to be able to load {:?} as a set bundle",
&setpath
));
let mut setcards = set.cards; let mut setcards = set.cards;
cards.append(&mut setcards); cards.append(&mut setcards);
} }