1use std::sync::Arc;
2
3use axum::Json;
4use axum::extract::{Path, State};
5use axum::http::StatusCode;
6use axum::response::IntoResponse;
7
8use crate::state::ApiState;
9use crate::types::*;
10
11#[utoipa::path(
12 get,
13 path = "/health",
14 responses(
15 (status = 200, description = "Service is healthy", body = HealthResponse)
16 )
17)]
18pub async fn health() -> Json<HealthResponse> {
19 Json(HealthResponse {
20 status: "ok",
21 version: env!("CARGO_PKG_VERSION"),
22 })
23}
24
25#[utoipa::path(
26 get,
27 path = "/sinks",
28 responses(
29 (status = 200, description = "List configured sinks", body = SinkListResponse)
30 )
31)]
32pub async fn list_sinks(State(state): State<Arc<ApiState>>) -> Json<SinkListResponse> {
33 Json(SinkListResponse {
34 sinks: state.sinks_info(),
35 })
36}
37
38#[utoipa::path(
39 get,
40 path = "/pipes",
41 responses(
42 (status = 200, description = "List configured pipes", body = PipeListResponse)
43 )
44)]
45pub async fn list_pipes(State(state): State<Arc<ApiState>>) -> Json<PipeListResponse> {
46 Json(PipeListResponse {
47 pipes: state.pipes_info(),
48 })
49}
50
51#[utoipa::path(
52 get,
53 path = "/pipe-presets",
54 responses(
55 (status = 200, description = "List reusable pipe presets", body = PipePresetListResponse)
56 )
57)]
58pub async fn list_pipe_presets(State(state): State<Arc<ApiState>>) -> Json<PipePresetListResponse> {
59 Json(PipePresetListResponse {
60 presets: state.pipe_presets_info(),
61 })
62}
63
64#[utoipa::path(
65 get,
66 path = "/pipes/{name}",
67 params(("name" = String, Path, description = "Pipe name")),
68 responses(
69 (status = 200, description = "Pipe details", body = PipeInfo),
70 (status = 404, description = "Pipe not found", body = ErrorResponse)
71 )
72)]
73pub async fn get_pipe(
74 State(state): State<Arc<ApiState>>,
75 Path(name): Path<String>,
76) -> Result<Json<PipeInfo>, impl IntoResponse> {
77 state
78 .pipes_info()
79 .into_iter()
80 .find(|p| p.name == name)
81 .map(Json)
82 .ok_or_else(|| {
83 (
84 StatusCode::NOT_FOUND,
85 Json(ErrorResponse {
86 error: format!("pipe not found: {name}"),
87 }),
88 )
89 })
90}
91
92#[utoipa::path(
93 get,
94 path = "/pipe-presets/{name}",
95 params(("name" = String, Path, description = "Pipe preset name")),
96 responses(
97 (status = 200, description = "Pipe preset details", body = PipePresetInfo),
98 (status = 404, description = "Pipe preset not found", body = ErrorResponse)
99 )
100)]
101pub async fn get_pipe_preset(
102 State(state): State<Arc<ApiState>>,
103 Path(name): Path<String>,
104) -> Result<Json<PipePresetInfo>, impl IntoResponse> {
105 state
106 .pipe_presets_info()
107 .into_iter()
108 .find(|preset| preset.name == name)
109 .map(Json)
110 .ok_or_else(|| {
111 (
112 StatusCode::NOT_FOUND,
113 Json(ErrorResponse {
114 error: format!("pipe preset not found: {name}"),
115 }),
116 )
117 })
118}