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};