Coverage Report

Created: 2024-02-20 21:15

/builds/xfbs/cindy/src/server/api/tags.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{server::Error, Cindy};
2
use axum::{
3
    extract::{Path, Query, State},
4
    routing::{get, patch},
5
    Json, Router,
6
};
7
use cindy_common::{
8
    api::*,
9
    tag::{Tag, TagNameInfo, TagValueInfo},
10
};
11
use std::collections::BTreeMap;
12
use tokio::task::spawn_blocking;
13
14
1
async fn tag_name_list(
15
1
    State(cindy): State<Cindy>,
16
1
) -> Result<Json<BTreeMap<String, TagNameInfo>>, Error> {
17
1
    let database = cindy.database().
await0
;
18
1
    spawn_blocking(move || database.tag_names().map(Json).map_err(Into::into)).await
?0
19
1
}
20
21
4
async fn tag_value_list(
22
4
    State(cindy): State<Cindy>,
23
4
    Query(query): Query<TagQuery<String>>,
24
4
) -> Result<Json<BTreeMap<Tag, TagValueInfo>>, Error> {
25
4
    let database = cindy.database().
await0
;
26
4
    spawn_blocking(move || {
27
4
        database
28
4
            .tag_list(query.name.as_deref(), query.value.as_deref())
29
4
            .map(Json)
30
4
            .map_err(Into::into)
31
4
    })
32
3
    .await
?0
33
4
}
34
35
7
async fn tag_value_create(
36
7
    State(cindy): State<Cindy>,
37
7
    Json(query): Json<TagValueCreateRequest<'static>>,
38
7
) -> Result<(), Error> {
39
7
    let database = cindy.database().
await0
;
40
7
    spawn_blocking(move || {
41
7
        database.tag_value_create(&query.name, &query.value)
?0
;
42
7
        if let Some(display) = &query.display {
43
7
            database.tag_value_display(&query.name, &query.value, display)
?0
;
44
0
        }
45
7
        Ok(())
46
7
    })
47
7
    .await
?0
48
7
}
49
50
2
async fn tag_value_delete(
51
2
    State(cindy): State<Cindy>,
52
2
    Query(query): Query<TagQuery<String>>,
53
2
) -> Result<(), Error> {
54
2
    let database = cindy.database().
await0
;
55
2
    spawn_blocking(move || {
56
2
        database
57
2
            .tag_delete(query.name.as_deref(), query.value.as_deref())
58
2
            .map_err(Into::into)
59
2
    })
60
2
    .await
?0
61
2
}
62
63
4
async fn tag_name_create(
64
4
    State(cindy): State<Cindy>,
65
4
    Json(query): Json<TagNameCreateRequest<'static>>,
66
4
) -> Result<(), Error> {
67
4
    let database = cindy.database().
await0
;
68
4
    spawn_blocking(move || {
69
4
        database.tag_name_create(&query.name, query.display.as_deref())
?0
;
70
4
        Ok(())
71
4
    })
72
4
    .await
?0
73
4
}
74
75
0
async fn tag_name_edit(
76
0
    State(cindy): State<Cindy>,
77
0
    Path(name): Path<String>,
78
0
    Json(query): Json<TagNameEditRequest<'static>>,
79
0
) -> Result<(), Error> {
80
0
    let mut database = cindy.database().await;
81
0
    spawn_blocking(move || {
82
0
        let transaction = database.transaction()?;
83
0
        if let Some(display) = &query.display {
84
0
            transaction.tag_name_display(&name, &display)?;
85
0
        }
86
0
        if let Some(name_new) = &query.name {
87
0
            transaction.tag_name_rename(&name, &name_new)?;
88
0
        }
89
0
        transaction.commit()?;
90
0
        Ok(())
91
0
    })
92
0
    .await?
93
0
}
94
95
16
pub fn router() -> Router<Cindy> {
96
16
    Router::new()
97
16
        .route(
98
16
            "/tags/values",
99
16
            get(tag_value_list)
100
16
                .delete(tag_value_delete)
101
16
                .post(tag_value_create),
102
16
        )
103
16
        .route("/tag/:name", patch(tag_name_edit))
104
16
        .route("/tags", get(tag_name_list).post(tag_name_create))
105
16
}