Skip to content

Commit

Permalink
Stage 0.5.0, add blocking feature. (#34)
Browse files Browse the repository at this point in the history
* Stage 0.5.0, add `blocking` feature.

* Add feature cfg to example

* Add example blocking

* Remove

* Let's try this again...

* More reorganization, add changelog
  • Loading branch information
bibi-reden authored Apr 29, 2024
1 parent 401ec44 commit 3929ba9
Show file tree
Hide file tree
Showing 18 changed files with 393 additions and 27 deletions.
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@
- `Released` type has been changed to a struct with an inner tuple value, though to get the regions, you use the functions:
- `Released::japan()`, `Released::global()`, and `Released::china()` for example.

## Fixes ⚒️
### Fixes ⚒️

- Applied a change to the `Student::position` function, was passing in the `Student::armor_type` for some reason... oops!

## 0.5.0 - 2024-04-01

### Additions ✨

Added the new `blocking` feature. It is not enabled by default, so you must require it if you wish to use it!

- This uses reqwest's `blocking` feature to handle all requests in a non-asynchronous way.

### Changes 📝

- Changed how some internal deserialization and hashing works in the crate.

### Fixes ⚒️
10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "blue_archive"
version = "0.4.0"
version = "0.5.0"
edition = "2021"
license-file = "LICENSE"
description = "A Blue Archive api wrapper for Rust, based off of SchaleDB's data: https://github.com/lonqie/SchaleDB"
Expand Down Expand Up @@ -33,3 +33,11 @@ strum_macros = "0.26"

# futures = "0.3"
# chrono = { version = "0.4", features = ["serde"] }

[features]
blocking = ["reqwest/blocking"]

[[example]]
name = "get_all_students"
path = "examples/blocking/get_all_students.rs"
required-features = ["blocking"]
14 changes: 14 additions & 0 deletions examples/blocking/get_all_students.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use anyhow::Result;
use blue_archive::Language;

pub fn main() -> Result<()> {
// You can obtain the students in a blocking context now.
let students = blue_archive::blocking::get_all_students(Language::English)?;
println!("# of students: {}", students.len());
// You may also use filtering and the StudentFetcher as you would usually do, though with blocking you will have to use the `new_blocking` function.
let fetched = blue_archive::StudentFetcher::new_blocking(Language::Japanese)?;
if let Some(student) = fetched.get_random_student() {
println!("Randomized Student: [{student}]")
}
Ok(())
}
2 changes: 1 addition & 1 deletion examples/fetch_currency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async fn main() -> anyhow::Result<()> {
println!("Pyroxenes");
println!("--------------------------");
println!(
"{:?}",
"{:#?}",
blue_archive::fetch_currency_by_name("Pyroxenes", Language::English)
.await?
.unwrap()
Expand Down
10 changes: 9 additions & 1 deletion examples/fetch_equipment.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
use blue_archive::Language;
use blue_archive::{types::equipment::EquipmentCategory, Language};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
for equipment in blue_archive::fetch_all_equipment(Language::English).await? {
println!("{}", equipment.name)
}

let hats = blue_archive::fetch_equipment_by_category(Language::English, EquipmentCategory::Hat)
.await?;

for hat in &hats {
println!("[{}] -> {}", hat.id, hat.name)
}

Ok(())
}
59 changes: 59 additions & 0 deletions src/api/blocking/currency.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::borrow::Borrow;

use crate::types::currency::Currency;

use crate::Language;

use super::{
internal::{get_response, Endpoint},
BlueArchiveError, Client, Result,
};

/**
Fetches all existing **[`Currency`]** currently in the database.
# Examples
```
use blue_archive::Language;
fn main() -> anyhow::Result<()> {
println!(
"Total Currencies: [{}]",
blue_archive::blocking::get_all_currencies(Language::English).len()
);
Ok(())
}
```
*/
fn get_all_currencies(language: impl Borrow<Language>) -> Result<Vec<Currency>, BlueArchiveError> {
Ok(
get_response(&Endpoint::Currency, language.borrow(), &Client::new())?
.json::<Vec<Currency>>()?,
)
}

/**
Fetches a specific **[`Currency`]** that matches with a provided **`name`** argument.
# Examples
```
use blue_archive::Language;
fn main() -> anyhow::Result<()> {
let pyroxenes_now = blue_archive::blocking::get_currency_by_name("Pyroxenes", Language::English)
.unwrap();
println!("Pyroxenes");
println!("--------------------------");
println!("{:?}", pyroxenes_now);
Ok(())
}
```
*/
pub fn get_currency_by_name(
name: impl AsRef<str>,
language: impl Borrow<Language>,
) -> Result<Option<Currency>, BlueArchiveError> {
Ok(get_all_currencies(language)?
.into_iter()
.find(|currency| currency.name.to_lowercase() == name.as_ref().to_lowercase()))
}
32 changes: 32 additions & 0 deletions src/api/blocking/enemy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::borrow::Borrow;

use crate::types::enemy::Enemy;

use super::{
internal::{get_response, Endpoint},
BlueArchiveError, Client, Result,
};

use crate::Language;

/// Fetches all [`Enemy`]'s that are currently in the database.
pub fn get_all_enemies(language: impl Borrow<Language>) -> Result<Vec<Enemy>, BlueArchiveError> {
Ok(
get_response(&Endpoint::Enemies, language.borrow(), &Client::new())?
.json::<Vec<Enemy>>()?,
)
}

/**
Fetches a specific **[`Enemy`]** that matches with a provided **`name`** argument.
*/
pub fn get_enemy_by_name(
language: impl Borrow<Language>,
name: impl AsRef<str>,
) -> Result<Option<Enemy>, BlueArchiveError> {
Ok(get_all_enemies(language)?
.into_iter()
.find(|enemy| enemy.name.to_lowercase() == name.as_ref().to_lowercase()))
}
41 changes: 41 additions & 0 deletions src/api/blocking/equipment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use std::borrow::Borrow;

use crate::types::equipment::{Equipment, EquipmentCategory};

use crate::Language;

use super::{
internal::{get_response, Endpoint},
BlueArchiveError, Client, Result,
};

/** Fetches all equipment in the database. */
pub fn get_all_equipment(
language: impl Borrow<Language>,
) -> Result<Vec<Equipment>, BlueArchiveError> {
Ok(
get_response(&Endpoint::Equipment, language.borrow(), &Client::new())?
.json::<Vec<Equipment>>()?,
)
}

/** Fetches all equipment that is equal to the given **`name`**. */
pub fn get_equipment_by_name(
language: impl Borrow<Language>,
name: impl AsRef<str>,
) -> Result<Option<Equipment>, BlueArchiveError> {
Ok(get_all_equipment(language)?
.into_iter()
.find(|equipment| equipment.name.to_lowercase() == name.as_ref().to_lowercase()))
}

/** Fetches all equipment that is equal to the given **[`EquipmentCategory`]**. */
pub fn get_equipment_by_category(
language: impl Borrow<Language>,
category: EquipmentCategory,
) -> Result<Vec<Equipment>, BlueArchiveError> {
Ok(get_all_equipment(language)?
.into_iter()
.filter(|equipment| equipment.category == category)
.collect::<Vec<_>>())
}
14 changes: 14 additions & 0 deletions src/api/blocking/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub mod currency;
pub mod enemy;
pub mod equipment;
pub mod raid;
pub mod student;
pub mod summon;

use anyhow::Result;

use super::internal;
use crate::BlueArchiveError;
use reqwest::blocking::Client;

pub use self::{currency::*, enemy::*, equipment::*, raid::*, student::*, summon::*};
17 changes: 17 additions & 0 deletions src/api/blocking/raid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! Functions primarily for geting [`RaidData`].
use std::borrow::Borrow;

use anyhow::Result;

use crate::{types::RaidData, Language};

use super::{
internal::{get_response, Endpoint},
BlueArchiveError, Client,
};

/// Fetches **[`RaidData`]**, which contains information related to raids in Blue Archive.
pub fn get_raid_data(language: impl Borrow<Language>) -> Result<RaidData, BlueArchiveError> {
Ok(get_response(&Endpoint::Raids, language.borrow(), &Client::new())?.json::<RaidData>()?)
}
106 changes: 106 additions & 0 deletions src/api/blocking/student.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//! Functions primarily for geting [`Student`] data.
use std::borrow::Borrow;

use rand::seq::IteratorRandom;

use crate::{
filter::student::StudentFilterOptions,
types::{students::student::StudentImageData, Student},
Language,
};

use super::{
internal::{get_response, Endpoint},
BlueArchiveError, Client, Result,
};

/// Fetches all students with extra data, which includes the images of the **[`Students`][`Student`]** among other things.
pub fn get_all_students(language: impl Borrow<Language>) -> Result<Vec<Student>, BlueArchiveError> {
let client = Client::new();
let mut students =
get_response(&Endpoint::Students, language.borrow(), &client)?.json::<Vec<Student>>()?;

students
.iter_mut()
.for_each(|student| student.image = StudentImageData::new(student));

Ok(students)
}

/**
Fetches a **[`Student`]** by a `name` from a set of names.
## Different Methods
- Searching with an associated tag, such as **`Iori (Swimsuit)`**
- It is recommended to use the last name and an associated tag if you are looking for a **[`Student`]** with a different appearance.
- Searching via. the **last name (`surname`)**.
- Searching via. the **first name**.
- Searching via. the **first name and last name together**, and vise versa (e.g. Asuna Ichinose/Ichinose Asuna).
# Examples
```
use anyhow::Result;
use blue_archive::Language;
fn main() -> Result<()> {
// Fetching asuna is relatively simple...
let asuna = blue_archive::blocking::get_student_by_name("Asuna", Language::English)?.unwrap();
println!("{}", asuna);
Ok(())
}
```
*/
pub fn get_student_by_name(
name: impl AsRef<str>,
language: impl Borrow<Language>,
) -> Result<Option<Student>, BlueArchiveError> {
let mut matched_student = None;

for student in get_all_students(language)? {
let lowercased = name.as_ref().to_lowercase();
let maybe_student = (lowercased == student.name.to_lowercase()
|| lowercased == student.first_name.to_lowercase()
|| lowercased == student.last_name.to_lowercase()
|| lowercased == student.full_name_last().to_lowercase()
|| lowercased == student.full_name_first().to_lowercase())
.then_some(student);
if let Some(student) = maybe_student {
matched_student = Some(student);
break;
}
}

Ok(matched_student)
}

/// Attempts to get a random **[`Student`]**.
///
/// If geting the data fails, then it will return a [`BlueArchiveError`], as the data would not have any **[`Students`][`Student`]**.
pub fn get_random_student(
language: impl Borrow<Language>,
) -> Result<Option<Student>, BlueArchiveError> {
Ok(get_all_students(language)?
.into_iter()
.choose(&mut rand::thread_rng()))
}

/// Attempts to get a random amount of **[`Students`][`Student`]** depending on the specified **`amount`**.
///
/// Depending on the **`amount`** inserted, if it exceeds the total length of **[`Students`][`Student`]** from the data, it will just return everything.
///
/// If geting the data fails, then it will return a [`BlueArchiveError`], as the data would not have any **[`Students`][`Student`]**.
pub fn get_random_students(
language: impl Borrow<Language>,
amount: usize,
) -> Result<Vec<Student>, BlueArchiveError> {
Ok(get_all_students(language)?
.into_iter()
.choose_multiple(&mut rand::thread_rng(), amount))
}

/// Returns **[`StudentFilterOptions`]** to be used with the provided **[`Vec<Student>`]** for filtering.
pub fn filter(students: &Vec<Student>) -> StudentFilterOptions {
StudentFilterOptions::new(students)
}
18 changes: 18 additions & 0 deletions src/api/blocking/summon.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//! Functions primarily for geting [`Summon`] data.
use std::borrow::Borrow;

use crate::{types::Summon, Language};

use super::{
internal::{get_response, Endpoint},
BlueArchiveError, Client,
};

/// Fetches all **[`Summons`][`Summon`]** from the data.
pub fn get_all_summons(language: impl Borrow<Language>) -> Result<Vec<Summon>, BlueArchiveError> {
Ok(
get_response(&Endpoint::Summons, language.borrow(), &Client::new())?
.json::<Vec<Summon>>()?,
)
}
Loading

0 comments on commit 3929ba9

Please sign in to comment.