Skip to main content

rust_mc_status/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2//! # rust-mc-status
3//!
4//! High-performance asynchronous Rust library for querying Minecraft server
5//! status — Java Edition and Bedrock Edition.
6//!
7//! ## Quick start
8//!
9//! ```rust,no_run
10//! use rust_mc_status::{ping_java, ping_bedrock, StatusExt};
11//!
12//! #[tokio::main]
13//! async fn main() -> Result<(), rust_mc_status::McError> {
14//!     // One-shot facade — no setup required
15//!     let java = ping_java("mc.hypixel.net").await?;
16//!     println!("{} — {} ms", java.motd_clean(), java.latency_ms() as u32);
17//!
18//!     let bedrock = ping_bedrock("geo.hivebedrock.network").await?;
19//!     println!("{} [{}]", bedrock.motd_clean(), bedrock.edition());
20//!     Ok(())
21//! }
22//! ```
23//!
24//! ## Using a client
25//!
26//! Build a [`McClient`] when you need custom timeouts, caching, or a proxy.
27//! `McClient::builder()` is the **only** constructor — there is no `new()`.
28//!
29//! ```rust,no_run
30//! use rust_mc_status::{McClient, StatusExt};
31//! use std::time::Duration;
32//!
33//! #[tokio::main]
34//! async fn main() -> Result<(), rust_mc_status::McError> {
35//!     let client = McClient::builder()
36//!         .timeout(Duration::from_secs(5))
37//!         .max_parallel(20)
38//!         .response_cache(Duration::from_secs(30), 256)
39//!         .build();
40//!
41//!     let status = client.java("mc.hypixel.net").await?;
42//!     println!("{}", status.display_players()); // "21000/200000"
43//!     println!("{:.0} ms", status.latency_ms());
44//!     println!("cached: {}", status.is_cached());
45//!     Ok(())
46//! }
47//! ```
48//!
49//! ## Batch pings
50//!
51//! [`McClient::ping_many`] pings multiple servers concurrently using a
52//! semaphore — slow or timed-out servers never block the rest.
53//!
54//! ```rust,no_run
55//! use rust_mc_status::{McClient, ServerEdition, ServerInfo};
56//!
57//! #[tokio::main]
58//! async fn main() -> Result<(), rust_mc_status::McError> {
59//!     let client = McClient::builder().max_parallel(10).build();
60//!     let servers = vec![
61//!         ServerInfo { address: "mc.hypixel.net".into(), edition: ServerEdition::Java },
62//!         ServerInfo { address: "geo.hivebedrock.network".into(), edition: ServerEdition::Bedrock },
63//!     ];
64//!     for (server, result) in client.ping_many(&servers).await {
65//!         match result {
66//!             Ok(s)  => println!("{} — {} ms", server.address, s.latency),
67//!             Err(e) => println!("{} — ❌ {e}", server.address),
68//!         }
69//!     }
70//!     Ok(())
71//! }
72//! ```
73//!
74//! ## Error handling
75//!
76//! [`McError`] is a two-level hierarchy — match broadly or drill into details:
77//!
78//! ```rust,no_run
79//! use rust_mc_status::{McClient, McError, StatusExt};
80//! use rust_mc_status::error::{NetworkError, ProtocolError};
81//!
82//! #[tokio::main]
83//! async fn main() {
84//!     let client = McClient::builder().build();
85//!     match client.java("mc.hypixel.net").await {
86//!         Ok(s) => println!("online: {}", s.display_players()),
87//!         Err(McError::Network(NetworkError::Timeout))       => println!("timed out"),
88//!         Err(McError::Network(NetworkError::Dns(msg)))      => println!("DNS: {msg}"),
89//!         Err(McError::Protocol(ProtocolError::InvalidResponse(msg))) => println!("bad packet: {msg}"),
90//!         Err(e) => println!("other: {e}"),
91//!     }
92//! }
93//! ```
94//!
95//! ## Optional features
96//!
97//! | Feature | What it adds |
98//! |---------|-------------|
99//! | `proxy` | SOCKS5 and HTTP CONNECT proxy support via [`ProxyConfig`] |
100//! | `tower` | [`McService`] — wrap `McClient` in Tower middleware (retries, rate-limiting, etc.) |
101//! | `full`  | Both `proxy` and `tower` |
102//!
103//! ```toml
104//! [dependencies]
105//! rust-mc-status = { version = "3", features = ["full"] }
106//! ```
107//!
108//! ## Crate structure
109//!
110//! | Module | Contents |
111//! |--------|----------|
112//! | *(root)* | [`McClient`], [`McClientBuilder`], [`ping_java`], [`ping_bedrock`] |
113//! | [`error`] | [`McError`] and sub-error types |
114//! | [`models`] | [`ServerStatus`], [`ServerData`], [`JavaStatus`], [`BedrockStatus`], etc. |
115//! | [`status`] | [`JavaServerStatus`], [`BedrockServerStatus`], [`StatusExt`] trait |
116//! | [`proxy`] | [`ProxyConfig`] *(feature = "proxy")* |
117//! | [`service`] | [`McService`], [`McRetryPolicy`] *(feature = "tower")* |
118//! | [`core`] | Internal DNS resolver, response cache, address parser *(not stable API)* |
119
120pub mod core;
121pub mod client;
122pub mod error;
123pub mod models;
124pub mod protocol;
125pub mod proxy;
126pub mod status;
127
128#[cfg(feature = "tower")]
129#[cfg_attr(docsrs, doc(cfg(feature = "tower")))]
130pub mod service;
131
132pub use client::{McClient, McClientBuilder, ping_java, ping_bedrock};
133pub use client::{JavaPingBuilder, BedrockPingBuilder, ServerPingBuilder};
134pub use error::{McError, NetworkError, ProtocolError, ConfigError};
135#[cfg(feature = "proxy")]
136#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
137pub use error::ProxyError;
138pub use models::*;
139pub use models::CacheStats;
140pub use models::{PingResult, LegacyData, QueryData};
141pub use proxy::{ProxyConfig, ProxyKind};
142pub use status::{JavaServerStatus, BedrockServerStatus, StatusExt, strip_formatting, truncate_str};
143
144#[cfg(feature = "tower")]
145#[cfg_attr(docsrs, doc(cfg(feature = "tower")))]
146pub use service::{McService, McRetryPolicy, PingRequestTower, PingResponseTower};