minehut 2.0.0

Simple, easy to use Rust wrapper for the Minehut API
Documentation
//! This is the products module accessible from the crate folder. It contains
//! all information related to Minehut products.
//! 
//! This module provides functions for:
//! 
//! * Retrieving all products from Minehut.
//! * Filtering Minehut products.
//! * Getting products by name or searching for it.

use crate::http;
use crate::models::Product;

/// Products can be of 9 different types, this enumerates those 
/// specific types for later.
pub enum Category {
    /// Product is a Minecraft plugin.
    Plugin, 
    /// Built custom map or world.
    World,
    /// Skripts files.
    Script, 
    /// Complete server setup.
    ServerSetup,
    /// Server mini game setup.
    Minigame,
    /// Schematic files used for building.
    Schematic, 
    /// Configuration.
    Configuration,
    /// Bundle of mods.
    Modpack, 
    /// Plugin that costs money.
    PremiumPlugin
}

/// Gets all products from Minehut asynchronously.
/// 
/// # Example
/// 
/// ```
/// async fn print_expensive_products() -> Result<(), minehut::Error> {
///     use minehut::products;
/// 
///     // Print all icons with price over 700
///     products::all().await?.into_iter().for_each(|p| {
///         if(p.price > 700) {
///             println!("{} is expensive", p.title);
///         }    
///     });
///     
///     Ok(())
/// }
/// ```
/// 
/// # Error
/// 
/// Returns an error if Reqwest could not fetch the data or if it could not 
/// parse the JSON. This is usually a network problem.
pub async fn all() -> Result<Vec<Product>, crate::Error> {
    http::req_data::<Vec<Product>>(
            "https://facade-service-prod.superleague.com/facade/v1/client/products"
    ).await
}

/// Gets all products of a specific category asynchronously.
/// 
/// # Arguments
/// 
/// * `category` - Category to filter products with.
/// 
/// # Example
/// 
/// ```
/// use minehut::products;
/// 
/// async fn print_plugins() {
///     // Printing all available plugins
///     products::of_category(products::Category::Plugin).await.unwrap().into_iter().for_each(|p| {
///         println!("{} is a plugin", p.title);
///     })
/// }
/// ```
/// 
/// # Error
/// 
/// Returns an error if Reqwest could not fetch the data from path or if it failed
/// to parse JSON. Both of these are usually network errors.
pub async fn of_category(category: Category) -> Result<Vec<Product>, crate::Error> {
    let category = match category {
        Category::Plugin => "Plugin",
        Category::World =>"World",
        Category::Script => "Script",
        Category::ServerSetup => "Server Setup",
        Category::Minigame => "Minigame",
        Category::Schematic => "Schematic",
        Category::Configuration => "Configuration",
        Category::Modpack => "Modpack",
        Category::PremiumPlugin => "Premium Plugin"
    };

    let filtered_icons = all().await?.into_iter().filter(
        |p| p.category == category

    ).collect();

    Ok(filtered_icons)
}

/// Returns all products which contain a specific name in their title.
/// 
/// # Arguments
/// 
/// * `query` - String slice to query products.
/// 
/// # Example
/// 
/// ```
/// #[tokio::main]
/// async fn main() {
///     use minehut::products;
///     
///     // Getting all products with "Skript" in its name
///     products::search("Skript").await.unwrap().into_iter().for_each(|p| {
///         println!("{}", p.title);
///     })
/// }
/// ```
/// 
/// # Error
/// 
/// Returns an error if  Reqwest could not fetch data from the path or if it failed 
/// to parse the response JSON. Usually network errors.
pub async fn search(query: &str) -> Result<Vec<Product>, crate::Error> {
    let filtered_products = all().await?.into_iter().filter(|p| p.title.contains(query)).collect();

    Ok(filtered_products)
}