| Crates.io | faceit |
| lib.rs | faceit |
| version | 0.1.0 |
| created_at | 2025-12-08 14:04:16.500455+00 |
| updated_at | 2025-12-08 14:04:16.500455+00 |
| description | A Rust client library for the FACEIT Public API |
| homepage | https://github.com/muijf/faceit |
| repository | https://github.com/muijf/faceit |
| max_upload_size | |
| id | 1973586 |
| size | 304,049 |

A Rust client library for the FACEIT Public API
Type-safe, async API client with comprehensive error handling, builder pattern configuration, and full Data API v4 support.
Key Features: Builder pattern • Ergonomic APIs • Comprehensive error handling • Full async/await support • Automatic JSON deserialization • API key and access token support • Feature flags for customization • Full Data API v4 coverage
Add this to your Cargo.toml:
[dependencies]
faceit = "0.1.0"
tokio = { version = "1", features = ["full"] }
Note: This library requires an async runtime. Tokio is recommended, but any async runtime compatible with
reqwestwill work.
Most features are optional to keep the core library lightweight. Enable only what you need.
Core Features:
default - Enables all default features (ergonomic, rustls-tls)ergonomic - Enables ergonomic API wrappers for Player, Match, Game, Hub, and Championshiprustls-tls - Uses rustls as the TLS backend for reqwest (default, recommended)native-tls - Uses native-tls as the TLS backend for reqwestQuick examples:
# Default (includes ergonomic APIs and rustls)
faceit = "0.1.0"
# Minimal setup (without ergonomic APIs)
faceit = { version = "0.1.0", default-features = false, features = ["rustls-tls"] }
# With native-tls instead of rustls
faceit = { version = "0.1.0", default-features = false, features = ["ergonomic", "native-tls"] }
use faceit::HttpClient;
#[tokio::main]
async fn main() -> Result<(), faceit::error::Error> {
// Create a client
let client = HttpClient::new();
// Get player by ID
let player = client.get_player("player-id-here").await?;
println!("Player: {}", player.nickname);
if let Some(country) = player.country {
println!("Country: {}", country);
}
Ok(())
}
Output:
Player: PlayerName
Country: GB
For more examples and usage patterns, see the examples.
use faceit::HttpClient;
let client = HttpClient::new();
let player = client.get_player("player-id-here").await?;
use faceit::HttpClient;
let client = HttpClient::new();
// By nickname
let player = client.get_player_from_lookup(Some("player_nickname"), None, None).await?;
// By nickname and game
let player = client.get_player_from_lookup(Some("player_nickname"), Some("cs2"), None).await?;
// By game_player_id
let player = client.get_player_from_lookup(None, Some("cs2"), Some("game_player_id")).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let stats = client.get_player_stats("player-id", "cs2").await?;
use faceit::HttpClient;
let client = HttpClient::new();
let history = client.get_player_history(
"player-id",
"cs2",
None, // from timestamp (optional)
None, // to timestamp (optional)
Some(0), // offset
Some(20), // limit
).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let bans = client.get_player_bans("player-id", Some(0), Some(20)).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let match_details = client.get_match("match-id-here").await?;
use faceit::HttpClient;
let client = HttpClient::new();
let stats = client.get_match_stats("match-id-here").await?;
use faceit::HttpClient;
let client = HttpClient::new();
let games = client.get_all_games(Some(0), Some(20)).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let game = client.get_game("cs2").await?;
use faceit::HttpClient;
let client = HttpClient::new();
let hub = client.get_hub("hub-id", None).await?;
// With expanded entities
let hub = client.get_hub("hub-id", Some(&["organizer", "game"])).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let matches = client.get_hub_matches(
"hub-id",
Some("all"), // type: "all", "upcoming", "ongoing", "past"
Some(0),
Some(20),
).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let championships = client.get_championships(
"cs2",
Some("all"), // type: "all", "upcoming", "ongoing", "past"
Some(0),
Some(10),
).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let championship = client.get_championship("championship-id", None).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let results = client.search_players(
"player_nickname",
Some("cs2"), // game filter (optional)
None, // country filter (optional)
Some(0),
Some(20),
).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let results = client.search_teams(
"team_nickname",
Some("cs2"), // game filter (optional)
Some(0),
Some(20),
).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let results = client.search_hubs(
"hub_name",
Some("cs2"), // game filter (optional)
Some("EU"), // region filter (optional)
Some(0),
Some(20),
).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let ranking = client.get_global_ranking(
"cs2",
"EU", // region (required)
None, // country filter (optional)
Some(0),
Some(20),
).await?;
use faceit::HttpClient;
let client = HttpClient::new();
let ranking = client.get_player_ranking(
"cs2",
"EU",
"player-id",
None, // country filter (optional)
Some(20),
).await?;
FACEIT Data API supports two types of authentication:
Both are passed using the Authorization: Bearer {token} header format. Authentication provides higher rate limits.
use faceit::HttpClient;
// Using an API key
let client = HttpClient::builder()
.api_key("your-api-key")
.build()?;
// Using an access token
let client = HttpClient::builder()
.api_key("your-access-token")
.build()?;
For advanced configuration:
use faceit::HttpClient;
use std::time::Duration;
let client = HttpClient::builder()
.api_key("your-api-key")
.timeout(Duration::from_secs(60))
.base_url("https://custom-api.example.com")
.build()?;
The ergonomic APIs provide a convenient way to work with resources without needing to pass IDs to each method call. Enable the
ergonomicfeature to use these APIs.
The ergonomic APIs wrap resources (Player, Match, Game, Hub, Championship) and store the ID, allowing you to call methods without passing it each time.
use faceit::{HttpClient, http::ergonomic::Player};
let client = HttpClient::new();
let player = Player::new("player-id-here", &client);
// No need to pass player ID each time
let player_data = player.get().await?;
let stats = player.stats("cs2").await?;
let history = player.history("cs2", None, None, Some(0), Some(20)).await?;
let bans = player.bans(Some(0), Some(20)).await?;
let hubs = player.hubs(Some(0), Some(50)).await?;
let teams = player.teams(Some(0), Some(20)).await?;
let tournaments = player.tournaments(Some(0), Some(20)).await?;
use faceit::{HttpClient, http::ergonomic::Match};
let client = HttpClient::new();
let match_obj = Match::new("match-id-here", &client);
let match_data = match_obj.get().await?;
let stats = match_obj.stats().await?;
use faceit::{HttpClient, http::ergonomic::Game};
let client = HttpClient::new();
let game = Game::new("cs2", &client);
let game_data = game.get().await?;
let parent = game.parent().await?;
let matchmakings = game.matchmakings(Some("EU"), Some(0), Some(20)).await?;
use faceit::{HttpClient, http::ergonomic::Hub};
let client = HttpClient::new();
let hub = Hub::new("hub-id-here", &client);
let hub_data = hub.get(None).await?;
let matches = hub.matches(Some("all"), Some(0), Some(20)).await?;
let members = hub.members(Some(0), Some(50)).await?;
let stats = hub.stats(Some(0), Some(20)).await?;
use faceit::{HttpClient, http::ergonomic::Championship};
let client = HttpClient::new();
let championship = Championship::new("championship-id-here", &client);
let championship_data = championship.get(None).await?;
let matches = championship.matches(Some("all"), Some(0), Some(20)).await?;
You can also create ergonomic API instances directly:
use faceit::{HttpClient, http::ergonomic::{Player, Match, Game, Hub, Championship}};
let client = HttpClient::new();
let player = Player::new("player-id-here", &client);
let match_obj = Match::new("match-id-here", &client);
let game = Game::new("cs2", &client);
let hub = Hub::new("hub-id-here", &client);
let championship = Championship::new("championship-id-here", &client);
The library provides comprehensive error types:
use faceit::error::Error;
match result {
Ok(data) => println!("Success: {:?}", data),
Err(Error::MissingParameter(msg)) => eprintln!("Missing required parameter: {}", msg),
Err(Error::InvalidApiKey) => eprintln!("Invalid API key or access token"),
Err(Error::Http(e)) => eprintln!("HTTP error: {}", e),
Err(Error::Api(status, msg)) => eprintln!("API error {}: {}", status, msg),
Err(Error::ServerError) => eprintln!("Server error (500)"),
Err(e) => eprintln!("Other error: {}", e),
}
FACEIT API error codes:
400 - Bad request401 - Unauthorized (invalid API key or access token)403 - Forbidden404 - Not found429 - Too many requests500 - Server error503 - Service temporarily unavailableRun any example with:
cargo run --example <name>
Core Examples:
basic_usage - Basic API usage with all methodsergonomic_api - Ergonomic API usage (requires ergonomic feature)use faceit::HttpClient;
#[tokio::main]
async fn main() -> Result<(), faceit::error::Error> {
let client = HttpClient::new();
// Get player
let player = client.get_player("player-id-here").await?;
println!("Player: {}", player.nickname);
// Get player stats
let stats = client.get_player_stats("player-id", "cs2").await?;
// Get match details
let match_details = client.get_match("match-id-here").await?;
// Search for players
let results = client.search_players("player_name", Some("cs2"), None, Some(0), Some(20)).await?;
// Get global ranking
let ranking = client.get_global_ranking("cs2", "EU", None, Some(0), Some(20)).await?;
Ok(())
}
Format code:
cargo fmt --all
Formats all Rust code according to the official style guide.
Lint code:
cargo clippy --all-targets --all-features -- -D warnings
Runs Clippy linter with all targets and features enabled, treating warnings as errors.
Run tests:
cargo test --all-features
Runs all tests with all features enabled to ensure comprehensive coverage.
Run doc tests:
cargo test --doc
Runs documentation tests to ensure all code examples compile and work correctly.
Editor setup: Recommended extensions are available in
.vscode/extensions.json. See CONTRIBUTING.md for development guidelines and pre-commit hooks.
For more information about authentication, see the FACEIT Developer Documentation.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.