Skip to main content

wekan_cli/client/
system.rs

1use std::collections::BTreeMap;
2
3use reqwest::header::ACCEPT;
4use serde::{Deserialize, Serialize};
5
6use super::{ClientError, WekanClient, transport::decode_success};
7
8#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
9#[serde(
10    deny_unknown_fields,
11    rename_all(deserialize = "camelCase", serialize = "snake_case")
12)]
13pub struct SchemaUpgradeState {
14    pub running: bool,
15    pub product: String,
16    pub app_version: String,
17    #[serde(deserialize_with = "nullable_date")]
18    pub started_at: Option<String>,
19    #[serde(deserialize_with = "nullable_date")]
20    pub finished_at: Option<String>,
21    pub current_step: String,
22    pub gated: bool,
23    pub steps: BTreeMap<String, SchemaUpgradeStepState>,
24    #[serde(deserialize_with = "required_nullable")]
25    pub last_check: Option<SchemaUpgradeLastCheck>,
26}
27
28#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
29#[serde(deny_unknown_fields)]
30pub struct SchemaUpgradeStepState {
31    pub status: SchemaUpgradeStepStatus,
32    pub fixed: i32,
33    pub unresolved: i32,
34    #[serde(default, deserialize_with = "present")]
35    pub error: Option<String>,
36}
37
38#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
39#[serde(rename_all = "snake_case")]
40pub enum SchemaUpgradeStepStatus {
41    Pending,
42    Checking,
43    Running,
44    Done,
45    Skipped,
46    Error,
47}
48
49#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
50#[serde(deny_unknown_fields)]
51pub struct SchemaUpgradeLastCheck {
52    pub version: String,
53    #[serde(deserialize_with = "date")]
54    pub at: String,
55}
56
57fn required_nullable<'de, D: serde::Deserializer<'de>, T: Deserialize<'de>>(
58    d: D,
59) -> Result<Option<T>, D::Error> {
60    Option::<T>::deserialize(d)
61}
62
63fn present<'de, D: serde::Deserializer<'de>, T: Deserialize<'de>>(
64    d: D,
65) -> Result<Option<T>, D::Error> {
66    T::deserialize(d).map(Some)
67}
68
69fn validate_date<E: serde::de::Error>(value: &str) -> Result<(), E> {
70    super::datetime::validate_response_date(value)
71        .map_err(|()| E::custom("invalid schema-upgrade date-time"))
72}
73
74fn date<'de, D: serde::Deserializer<'de>>(d: D) -> Result<String, D::Error> {
75    let value = String::deserialize(d)?;
76    validate_date::<D::Error>(&value)?;
77    Ok(value)
78}
79
80fn nullable_date<'de, D: serde::Deserializer<'de>>(d: D) -> Result<Option<String>, D::Error> {
81    let value = Option::<String>::deserialize(d)?;
82    if let Some(value) = &value {
83        validate_date::<D::Error>(value)?;
84    }
85    Ok(value)
86}
87
88impl WekanClient {
89    pub async fn schema_upgrade_status(&self) -> Result<SchemaUpgradeState, ClientError> {
90        let mut endpoint =
91            self.server()
92                .join("schema-upgrade-status")
93                .map_err(|_| ClientError::Protocol {
94                    diagnostic: None,
95                    message: "could not build the schema-upgrade status endpoint".into(),
96                    success_status_received: false,
97                })?;
98        endpoint.query_pairs_mut().append_pair("json", "1");
99        let body = self
100            .execute_success_request(self.http.get(endpoint).header(ACCEPT, "application/json"))
101            .await?;
102        decode_success(&body, "schema-upgrade status", true)
103    }
104}