wsb-daemon 0.248.6265

wsb's daemon: the workbench, the GitHub mirror's schedule and peer continuity, for every workspace on the machine
//! Gists: the list from the machine's mirror, a gist's contents fetched once
//! and then served from it, and edits written through GitHub.

use axum::{
    extract::{Path, State},
    Json,
};
use serde_json::json;

use crate::web::github::{self, Refusal};
use crate::web::state::WebState;
use wsb_github::client::{CreateGistRequest, UpdateGistRequest};

/// GET /api/v1/gists — the mirrored list, with how current it is.
pub async fn list_gists(State(state): State<WebState>) -> Result<Json<serde_json::Value>, Refusal> {
    let service = github::of(&state)?.service.clone();
    let listed = github::blocking(move || service.gists()).await?;
    Ok(Json(json!({ "gists": listed.items, "sync": listed.sync })))
}

/// POST /api/v1/gists/refresh — bring the machine's mirror current now.
pub async fn refresh_gists(
    State(state): State<WebState>,
) -> Result<Json<wsb_github::sync::SyncReport>, Refusal> {
    super::issues::refresh(&state).await.map(Json)
}

/// GET /api/v1/gists/:id — one gist with its file contents.
///
/// The mirror answers when it holds the whole gist; a gist held only as a
/// list summary is read from GitHub once and kept.
pub async fn get_gist(
    State(state): State<WebState>,
    Path(gist_id): Path<String>,
) -> Result<Json<wsb_github::service::GistAnswer>, Refusal> {
    let github = github::of(&state)?;
    let client = github::client().ok();
    github
        .service
        .gist(client.as_ref(), &gist_id)
        .await
        .map(Json)
        .map_err(github::failure)
}

pub async fn create_gist(
    State(state): State<WebState>,
    Json(body): Json<CreateGistRequest>,
) -> Result<Json<serde_json::Value>, Refusal> {
    let github = github::of(&state)?;
    let client = github::client()?;
    let gist = github
        .service
        .create_gist(&client, &body)
        .await
        .map_err(github::failure)?;
    Ok(Json(json!({ "gist": gist })))
}

pub async fn update_gist(
    State(state): State<WebState>,
    Path(gist_id): Path<String>,
    Json(body): Json<UpdateGistRequest>,
) -> Result<Json<serde_json::Value>, Refusal> {
    let github = github::of(&state)?;
    let client = github::client()?;
    let gist = github
        .service
        .update_gist(&client, &gist_id, &body)
        .await
        .map_err(github::failure)?;
    Ok(Json(json!({ "gist": gist })))
}