Skip to main content

oversync_api/
handlers.rs

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}