1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
//! A simple, easy to use Rust wrapper for the Minehut API.
//!
//! All functions that return/modify data in the crate use async/await.
//!
//! This module provides functions for:
//!
//! * Getting Minehut stats in an organized manner from the Minehut API.
//! * Client authentication allowing you to access and or modify more data.
//!
//! # Example
//! Creating a client instance:
//!
//! ```no_run
//! // Functions can be seen at the Client struct
//! let client = minehut::Client::new("auth-token", "session-id");
//!
//! // Do something with it
//! ```
pub mod models;
mod http;
mod handlers;
use std::fmt;
use crate::models::{PlayerDistribution, HomePageStats, SimpleStats, OwnedServer, OwnedServerRes};
pub use crate::handlers::{servers, products};
/// All error types for the crate. Used by the crate to propogate errors.
/// Users can use it for error handling.
#[derive(Debug)]
pub enum Error {
/// This is called if Reqwest produces an HTTP error.
Http(reqwest::Error),
/// This is called if Serde failed to parse the response. Usually this
/// means the data received is not what the crate expected.
Json(reqwest::Error),
/// This means the operation failed.
FailedOp(String)
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Http(e) => write!(f, "{}", e)?,
Error::Json(e) => write!(f, "{}", e)?,
Error::FailedOp(s) => write!(f, "{}", s)?
}
Ok(())
}
}
/// This is the Minehut client struct, it only stores an authentication
/// token and session ID. All data that require authentication can only
/// be ran using this struct.
pub struct Client {
/// The authentication token.
auth_token: String,
/// The session ID, this changes periodically.
session_id: String
}
impl Client {
/// Creates a new instance of Client with provided auth and session
/// ID. You can get both of these using the inspect element on the
/// Minehut dashboard.
///
/// # Arguments
///
/// * `auth` - Authentication token from Minehut.
/// * `session_id` - Session ID from Minehut.
///
/// # Example
///
/// ```no_run
/// use minehut::Client;
///
/// let client = Client::new("auth-token", "session-id");
/// // Now do something with
/// ```
pub fn new(auth_token: String, session_id: String) -> Self {
Client {
auth_token,
session_id
}
}
/// Retrieves a server that the client user owns by name using the Minehut
/// API.
///
/// # Arguments
///
/// * `name` - Name of the server.
///
/// # Example
///
/// ```no_run
/// let client = minehut::Client::new("","");
///
/// match client.my_server("weird-name").await {
/// Err(_) => println!("Cannot fetch server"),
/// Ok(s) => println!("{s:?}")
/// }
/// ```
///
/// # Error
///
/// Returns an error if a server could not be found or if found server is not owned
/// by the client user.
pub async fn my_server(&self, name: &str) -> Result<OwnedServer, Error> {
let id = handlers::servers::server_from_name(name).await?.id;
let server_res = http::req_client_data::<OwnedServerRes>(
&self,
&format!("server/{id}/server_data")
).await?;
Ok(server_res.server)
}
}
/// Gets a `SimpleStats` struct from Minehut asynchronously. Gets simple Minehut
/// statistics.
///
/// # Examples
///
/// ```
/// async fn print_stats() {
/// // It is safe to assume this will not return an error.
/// // As such we will unwrap() the result.
/// let stats = minehut::simple_stats().await.unwrap();
///
/// println!("{} players are on", stats.player_count);
/// println!("{} hosted servers", stats.server_count);
/// }
/// ```
///
/// # Error
///
/// Returns a HTTP error if it cannot load page, usually a network error.
pub async fn simple_stats() -> Result<SimpleStats, Error> {
http::req_data::<SimpleStats>("network/simple_stats").await
}
/// Gets a `PlayerDistribution` struct from Minehut asynchronously. Gets the player
/// distribution for Java and Bedrock on Minehut.
///
/// # Examples
///
/// ```
/// #[tokio::main]
/// async fn main() {
/// // It is safe to assume this will not return an error.
/// // As such, we will unwrap() the result.
/// let dist = minehut::player_distribution().await.unwrap();
///
/// println!("{} java players", dist.java_total);
/// println!("{} bedrock servers", dist.bedrock_player_server);
/// }
/// ```
///
/// # Error
///
/// Returns a HTTP error if it cannot load page, this is usally a network error.
pub async fn player_distribution() -> Result<PlayerDistribution, Error> {
http::req_data::<PlayerDistribution>("network/players/distribution").await
}
/// Gets a `HomePageStats` from Minehut asynchronously. Returns the home page
/// statistics.
///
/// # Examples
///
/// ```
/// #[tokio::main]
/// async fn main() {
/// // It is safe to assume this will not return an error.
/// // As such, we will unwrap() the result.
/// let home = minehut::home_page_stats().await.unwrap();
///
/// println!("{} users, {} server", home.user_count, home.server_count);
/// }
/// ```
///
/// # Error
///
/// Returns a HTTP error if it cannot load page, this is usally a network error.
pub async fn homepage_stats() -> Result<HomePageStats, Error> {
http::req_data::<HomePageStats>("network/homepage_stats").await
}