wekan_cli/client/
system.rs1use 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}