litchee 0.1.5

Async, builder-pattern Rust client for the Lichess API: full endpoint coverage, NDJSON streaming, and OAuth2 PKCE ('Log in with Lichess').
Documentation
//! Streaming and bulk export methods on [`GamesApi`] (NDJSON, no query builder).

use futures_util::stream::BoxStream;
use reqwest::Method;
use reqwest::header::ACCEPT;

use super::GamesApi;
use super::model::{LichessGame, LichessGameMoveUpdate};
use crate::config::Host;
use crate::error::Result;
use crate::http;
use crate::http::ACCEPT_NDJSON;

impl GamesApi<'_> {
    /// Streams the authenticated user's imported games (NDJSON).
    /// `GET /api/games/export/imports`
    pub async fn export_imports(&self) -> Result<BoxStream<'static, Result<LichessGame>>> {
        let request = self
            .client
            .request(Method::GET, Host::Default, "/api/games/export/imports")
            .header(ACCEPT, ACCEPT_NDJSON);
        http::stream(request, self.client.max_line_bytes()).await
    }

    /// Streams a game's moves as they are played. `GET /api/stream/game/{id}`
    pub async fn stream_moves(
        &self,
        game_id: &str,
    ) -> Result<BoxStream<'static, Result<LichessGameMoveUpdate>>> {
        let path = format!("/api/stream/game/{}", http::segment(game_id));
        let request = self.client.request(Method::GET, Host::Default, &path);
        http::stream(request, self.client.max_line_bytes()).await
    }

    /// Streams games played by the given users as they start/finish (NDJSON).
    ///
    /// `with_current_games` also includes each user's ongoing game at connect.
    /// `POST /api/stream/games-by-users`
    pub async fn stream_by_users(
        &self,
        usernames: &[&str],
        with_current_games: Option<bool>,
    ) -> Result<BoxStream<'static, Result<LichessGame>>> {
        let request = self
            .client
            .request(Method::POST, Host::Default, "/api/stream/games-by-users")
            .query(&[("withCurrentGames", with_current_games)])
            .text_body(usernames.join(","));
        http::stream(request, self.client.max_line_bytes()).await
    }

    /// Streams a custom set of games by id (NDJSON).
    /// `POST /api/stream/games/{streamId}`
    pub async fn stream_by_ids(
        &self,
        stream_id: &str,
        ids: &[&str],
    ) -> Result<BoxStream<'static, Result<LichessGame>>> {
        let path = format!("/api/stream/games/{}", http::segment(stream_id));
        let request = self
            .client
            .request(Method::POST, Host::Default, &path)
            .text_body(ids.join(","));
        http::stream(request, self.client.max_line_bytes()).await
    }

    /// Adds game ids to an existing game stream.
    /// `POST /api/stream/games/{streamId}/add`
    pub async fn add_to_stream(&self, stream_id: &str, ids: &[&str]) -> Result<()> {
        let path = format!("/api/stream/games/{}/add", http::segment(stream_id));
        let request = self
            .client
            .request(Method::POST, Host::Default, &path)
            .text_body(ids.join(","));
        http::ok(request).await
    }
}