rusty-lcu 0.1.0

Generated Rust client helpers for the League Client Update API
Documentation

rusty-lcu

A library for interacting with the LCU API in Rust. It provides a typed interface to the LCU endpoints, as well as utilities for polling, event streams, and credential management.

The endpoint layer is generated from schema/swagger.json, which is vendored from the Dysolix LCU swagger data. To regenerate from a newer schema, run scripts\update-swagger.ps1 on Windows or ./scripts/update-swagger.sh on Unix-like shells, then build normally. You can also set LCU_SWAGGER_PATH before building to generate from another local schema without replacing the vendored file.

Quick Start

use rusty_lcu::{generated, EndpointParams, LcuClient};

#[tokio::main]
async fn main() -> rusty_lcu::Result<()> {
    let mut client = LcuClient::new()?;
    client.connect().await?;

    let summoner = generated::get_lol_summoner_v1_current_summoner_typed(
        &client,
        EndpointParams::new(),
    )
    .await?;

    println!("{}", summoner.summoner_id);
    Ok(())
}

Path, Query, And Body Params

Generated functions take EndpointParams so every swagger endpoint has the same stable call shape. Endpoints with a named swagger response model also get a *_typed helper that returns a generated models::* type. Endpoints with a named swagger request body model also get *_with_body helpers, and endpoints with both named request and response models get *_with_body_typed. Required path parameters and required query parameters from the swagger are validated before the request is sent.

let summoner = generated::get_lol_summoner_v1_summoners_by_id(
    &client,
    EndpointParams::new().path("id", 123456789),
)
.await?;

let typed_summoner = generated::get_lol_summoner_v1_summoners_by_id_typed(
    &client,
    EndpointParams::new().path("id", 123456789),
)
.await?;

let result = generated::post_lol_lobby_v2_lobby(
    &client,
    EndpointParams::new().body(serde_json::json!({ "queueId": 430 }))?,
)
.await?;

let conversation: generated::models::LolChatConversationResource = todo!();
let updated = generated::put_lol_chat_v1_conversations_by_id_with_body_typed(
    &client,
    EndpointParams::new().path("id", &conversation.id),
    &conversation,
)
.await?;

For raw escape-hatch calls, use client.get, client.post, client.put, client.patch, client.delete, or client.request. Typed raw helpers are available as get_as, post_as, put_as, patch_as, delete_as, and request_as.

let phase: String = client
    .get_as("/lol-gameflow/v1/gameflow-phase")
    .await?;

Endpoint Discovery

use rusty_lcu::generated::{
    SCHEMA_VERSION, TAGS, endpoints_for_tag, find_endpoint,
};

let endpoint = find_endpoint("GET", "/lol-summoner/v1/current-summoner")
    .expect("generated endpoint");

println!("{} {:?}", endpoint.operation_id, endpoint.response_type);
println!("generated from LCU schema {SCHEMA_VERSION}");

for endpoint in endpoints_for_tag("Plugin lol-summoner") {
    println!("{} {}", endpoint.method, endpoint.path);
}

println!("available tag groups: {}", TAGS.len());

You can also inspect the generated surface without a running League client:

cargo run --example list_endpoints

With League running, this example connects to LCU and fetches the current summoner through a generated typed endpoint:

cargo run --example current_summoner

Polling

use rusty_lcu::{generated, EndpointParams, PollEvent, PollOptions};

client
    .poll_endpoint(
        &generated::GET_LOL_GAMEFLOW_V1_GAMEFLOW_PHASE,
        EndpointParams::new(),
        PollOptions::default(),
        |event| match event {
            PollEvent::DistinctResponse(phase) => phase == serde_json::json!("InProgress"),
            PollEvent::Response(_) | PollEvent::Error(_) => false,
        },
    )
    .await?;

Credentials

By default connect() tries to read credentials from the running LeagueClientUx process, falls back to the League lockfile at C:\Riot Games\League of Legends\lockfile on Windows, and waits for LCU to respond. You can override the lockfile with RUSTY_LCU_LOCKFILE, pass a specific lockfile path, pass lockfile content, or construct manual credentials:

use rusty_lcu::{Credentials, CredentialsSource, LcuClient};

let mut client = LcuClient::new()?;
client
    .connect_with(CredentialsSource::Manual(Credentials::new(51111, "password")))
    .await?;

Use connect_with_options to disable or customize the readiness check:

use rusty_lcu::{ConnectOptions, CredentialsSource, LcuClient};

let mut client = LcuClient::new()?;
client
    .connect_with_options(
        CredentialsSource::Process,
        ConnectOptions {
            readiness_check: None,
        },
    )
    .await?;

Events

use serde::Deserialize;
use rusty_lcu::{EventFilter, EventStream};

#[derive(Debug, Deserialize)]
struct GameflowPhase(String);

let mut events = client.event_stream().await?;
events.subscribe("OnJsonApiEvent").await?;

let filter = EventFilter::new()
    .uri("/lol-gameflow/v1/gameflow-phase")
    .event_type("Update");

while let Some(phase) = events.next_matching_event_as::<GameflowPhase>(&filter).await? {
    println!("{phase:?}");
}

Current Scope

This crate currently generates endpoint functions, endpoint metadata, and Rust models for the full swagger surface. Generic functions return serde_json::Value; typed helpers are generated where a request or response points at a named swagger component schema. Exotic inline OpenAPI shapes are represented as serde_json::Value inside generated models.