Skip to content
Clone
fcc12de
109 lines 3.4 KB Rust
use axum::extract::{Path, Query, State};
use export::rest::AppResponseData;
use serde::{Deserialize, Serialize};
use session::Session;
use utoipa::IntoParams;
use crate::errors::{ApiError, GitApiError};
use crate::handler::{RepoPath, require_writer};
use crate::service::GitService;
use crate::service::stars::{RepoStarResp, StargazerDto};
#[derive(Debug, Clone, Deserialize, IntoParams)]
pub struct StarsPath {
pub space_name: String,
pub repo_name: String,
}
#[derive(Debug, Clone, Deserialize, IntoParams)]
pub struct StarQuery {
pub limit: Option<u64>,
pub offset: Option<u64>,
}
#[derive(Debug, Clone, Serialize, utoipa::ToSchema)]
pub struct StarStatusResp {
pub starred: bool,
}
#[utoipa::path(
put,
path = "/repos/{space_name}/{repo_name}/star",
tag = "repos",
params(RepoPath),
responses(
(status = 200, description = "star repo", body = AppResponseData<RepoStarResp>)
)
)]
pub async fn star_repo(
State(service): State<GitService>,
session: Session,
Path(path): Path<RepoPath>,
) -> Result<AppResponseData<RepoStarResp>, ApiError> {
let (ctx, uid) = require_writer(&service, &session, path.space_name.clone(), path.repo_name.clone()).await?;
let out = service.star_repo(&ctx, uid).await.map_err(GitApiError::from)?;
Ok(AppResponseData::ok(out))
}
#[utoipa::path(
delete,
path = "/repos/{space_name}/{repo_name}/star",
tag = "repos",
params(RepoPath),
responses(
(status = 200, description = "unstar repo", body = AppResponseData<RepoStarResp>)
)
)]
pub async fn unstar_repo(
State(service): State<GitService>,
session: Session,
Path(path): Path<RepoPath>,
) -> Result<AppResponseData<RepoStarResp>, ApiError> {
let (ctx, uid) = require_writer(&service, &session, path.space_name.clone(), path.repo_name.clone()).await?;
let out = service.unstar_repo(&ctx, uid).await.map_err(GitApiError::from)?;
Ok(AppResponseData::ok(out))
}
#[utoipa::path(
get,
path = "/repos/{space_name}/{repo_name}/star",
tag = "repos",
params(RepoPath),
responses(
(status = 200, description = "check star status", body = AppResponseData<StarStatusResp>)
)
)]
pub async fn is_starred(
State(service): State<GitService>,
session: Session,
Path(path): Path<RepoPath>,
) -> Result<AppResponseData<StarStatusResp>, ApiError> {
let (ctx, uid) = require_writer(&service, &session, path.space_name.clone(), path.repo_name.clone()).await?;
let starred = service.is_starred(&ctx, uid).await.map_err(GitApiError::from)?;
Ok(AppResponseData::ok(StarStatusResp { starred }))
}
#[utoipa::path(
get,
path = "/repos/{space_name}/{repo_name}/stargazers",
tag = "repos",
params(RepoPath, StarQuery),
responses(
(status = 200, description = "list stargazers", body = AppResponseData<Vec<StargazerDto>>)
)
)]
pub async fn list_stargazers(
State(service): State<GitService>,
session: Session,
Path(path): Path<RepoPath>,
Query(q): Query<StarQuery>,
) -> Result<AppResponseData<Vec<StargazerDto>>, ApiError> {
let (ctx, _uid) = require_writer(&service, &session, path.space_name.clone(), path.repo_name.clone()).await?;
let limit = q.limit.unwrap_or(50).clamp(1, 100);
let offset = q.offset.unwrap_or(0);
let out = service.list_stargazers(&ctx, limit, offset).await.map_err(GitApiError::from)?;
Ok(AppResponseData::ok(out))
}
#[allow(dead_code)]
fn _typecheck(_: AppResponseData<RepoStarResp>) {}