minehut 1.0.1

Simple Rust wrapper for the Minehut API
Documentation
use once_cell::sync::OnceCell;
use crate::request;
use crate::models::ServerIcon;

/// All icons have a "rank", these ranks are of 5 types. This enumerates
/// those ranks for later use.
pub enum Rarity {
    /// not valuable
    Common,
    /// costs a bit
    Uncommon,
    /// valuable
    Rare,
    /// very valuable
    Epic,
    /// incredibly valuable
    Legendary
}

/// Gets all Minehut server icons asynchronously. Cached the info
/// for later use.
/// 
/// # Example
/// 
/// ```
/// use minehut::servers::icons;
/// 
/// async fn print_all_icons() {
///     // looping through icons
///     icons::all().await.into_iter().for_each(|i| {
///         println!("{:?}", i) // printing ServerIcon struct     
///     });
/// }
/// ```
pub async fn all() -> &'static [ServerIcon] {
    static ICONS: OnceCell<Vec<ServerIcon>> = OnceCell::new();

    if ICONS.get().is_none() {
        let icons = request::get_data::<Vec<ServerIcon>>(
            "/servers/icons"
        ).await;

        ICONS.set(icons).unwrap();
    }

    ICONS.get().unwrap()
}

/// Getting all icons of a specified rarity.
/// 
/// # Arguments
/// 
/// * `rarity` - Rarity to filter icons with
/// 
/// # Example
/// ```
/// use minehut::servers::icons;
/// use minehut::models::ServerIcon;
/// 
/// async fn common_icons() -> Vec<&'static ServerIcon> {
///     // getting all icons of rarity Common
///     return icons::of_rarity(icons::Rarity::Common).await;
/// }
/// ```
pub async fn of_rarity(rarity: Rarity) -> Vec<&'static ServerIcon> {
    let rarity = match rarity {
        Rarity::Common => "COMMON",
        Rarity::Uncommon => "UNCOMMON",
        Rarity::Rare => "RARE",
        Rarity::Epic => "EPIC",
        Rarity::Legendary => "LEGENDARY"
    };

    all().await.into_iter().filter(
        |i| i.rank == rarity

    ).collect()
}

/// Gets an icon from the specified ID.
/// 
/// # Arguments
/// 
/// * `id` - ID of the icon
/// 
/// # Example
/// 
/// ```
/// use minehut::servers::icons;
/// 
/// #[tokio::main]
/// async fn main() {
///     // get icon from ID
///     let icon = icons::icon_from_id("some-weird-id").await;
/// 
///     match icon {
///         None => println!("Didn't find an icon"),
///         Some(i) => println!("Found icon: {i:?}")
///     }
/// }
/// ```
/// 
/// # Errors
/// 
/// `icon_from_id(&str)` returns an Option<T> only if the ID given does 
/// not match to an icon
pub async fn icon_from_id(id: &str) -> Option<&'static ServerIcon> {
    all().await.into_iter().find(|i| i.id == id)
}

/// Gets an icon from the name specified asynchronously.
/// 
/// # Arguments
/// 
/// * `name` - Name of the icon
///
/// # Example
/// 
/// ```
/// use minehut::servers::icons;
/// 
/// #[tokio::main]
/// async fn main() {
///     let icon = icons::icon_from_name("ENDER_PEARL").await;
/// 
///     match icon {
///         None => println!("Didn't find an icon"),
///         Some(i) => println!("Found icon: {i:?}")
///     }
/// }
/// ```
/// 
/// # Errors
/// 
/// `icon_from_name(&str)` returns an Optio<T> only if the name given does
/// not match to an icon
pub async fn icon_from_name(name: &str) -> Option<&'static ServerIcon> {
    all().await.into_iter().find(|i| i.icon_name == name)
}