faceit

Crates.iofaceit
lib.rsfaceit
version0.1.0
created_at2025-12-08 14:04:16.500455+00
updated_at2025-12-08 14:04:16.500455+00
descriptionA Rust client library for the FACEIT Public API
homepagehttps://github.com/muijf/faceit
repositoryhttps://github.com/muijf/faceit
max_upload_size
id1973586
size304,049
Milan de Kruijf (milandekruijf)

documentation

https://docs.rs/faceit

README

FACEIT Banner

CI crates.io docs.rs license

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.

DocumentationExamplesContributingCode of Conduct


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


Table of Contents


Installation

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 reqwest will work.

Feature Flags

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 Championship
  • rustls-tls - Uses rustls as the TLS backend for reqwest (default, recommended)
  • native-tls - Uses native-tls as the TLS backend for reqwest

Quick 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"] }

Quick Start

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.

API Methods

Player Methods

Get Player by ID

use faceit::HttpClient;

let client = HttpClient::new();
let player = client.get_player("player-id-here").await?;

Get Player from Lookup

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

Get Player Stats

use faceit::HttpClient;

let client = HttpClient::new();
let stats = client.get_player_stats("player-id", "cs2").await?;

Get Player Match History

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

Get Player Bans

use faceit::HttpClient;

let client = HttpClient::new();
let bans = client.get_player_bans("player-id", Some(0), Some(20)).await?;

Match Methods

Get Match Details

use faceit::HttpClient;

let client = HttpClient::new();
let match_details = client.get_match("match-id-here").await?;

Get Match Statistics

use faceit::HttpClient;

let client = HttpClient::new();
let stats = client.get_match_stats("match-id-here").await?;

Game Methods

Get All Games

use faceit::HttpClient;

let client = HttpClient::new();
let games = client.get_all_games(Some(0), Some(20)).await?;

Get Game Details

use faceit::HttpClient;

let client = HttpClient::new();
let game = client.get_game("cs2").await?;

Hub Methods

Get Hub Details

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

Get Hub Matches

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

Championship Methods

Get Championships

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

Get Championship Details

use faceit::HttpClient;

let client = HttpClient::new();
let championship = client.get_championship("championship-id", None).await?;

Search Methods

Search Players

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

Search Teams

use faceit::HttpClient;

let client = HttpClient::new();
let results = client.search_teams(
    "team_nickname",
    Some("cs2"),  // game filter (optional)
    Some(0),
    Some(20),
).await?;

Search Hubs

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

Ranking Methods

Get Global Ranking

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

Get Player Ranking

use faceit::HttpClient;

let client = HttpClient::new();
let ranking = client.get_player_ranking(
    "cs2",
    "EU",
    "player-id",
    None,         // country filter (optional)
    Some(20),
).await?;

Using Authentication

FACEIT Data API supports two types of authentication:

  1. API Key - Server-side or client-side API keys obtained from the FACEIT Developer Portal
  2. Access Token - User access tokens obtained via OAuth2

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()?;

Builder Pattern

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()?;

Ergonomic APIs

The ergonomic APIs provide a convenient way to work with resources without needing to pass IDs to each method call. Enable the ergonomic feature 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.

Player API

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

Match API

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

Game API

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

Hub API

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

Championship API

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

Direct Instantiation

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

Error Handling

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 request
  • 401 - Unauthorized (invalid API key or access token)
  • 403 - Forbidden
  • 404 - Not found
  • 429 - Too many requests
  • 500 - Server error
  • 503 - Service temporarily unavailable

Examples

Run any example with: cargo run --example <name>

Core Examples:

Basic Usage Example

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(())
}

Development

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.

Rate Limits

  • Without authentication: Subject to standard rate limits
  • With API key or access token: Higher rate limits (check FACEIT documentation for current limits)

For more information about authentication, see the FACEIT Developer Documentation.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Commit count: 0

cargo fmt