1use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Deserialize)]
6pub(crate) struct Raw {
7 cutoff: u32,
8 last_check: String,
9 num_checks: u32,
10 check_frequency: u32,
11 urls: Vec<crate::url::Raw>,
12 version: u32,
13}
14
15#[derive(Debug, Clone, PartialOrd, PartialEq)]
17pub struct Status {
18 pub cutoff: u32,
20
21 pub last_check: chrono::DateTime<chrono::Utc>,
23
24 pub num_checks: u32,
26
27 pub check_frequency: u32,
29
30 pub urls: Vec<crate::Url>,
32
33 pub version: u32,
35}
36
37impl Status {
38 pub const URL: &'static str = "https://archlinux.org/mirrors/status/json";
40
41 pub async fn get() -> reqwest::Result<Self> {
43 let response = reqwest::get(Self::URL).await?;
44 let raw: Raw = response
45 .json()
46 .await
47 .expect("failed to parse response to json");
48
49 Ok(Self::from(raw))
50 }
51}
52
53impl From<Raw> for Status {
54 fn from(raw: Raw) -> Self {
55 let last_check: chrono::DateTime<chrono::Utc> = raw
56 .last_check
57 .parse()
58 .expect("failed to parse last_check field from raw status");
59 let urls: Vec<crate::Url> = raw.urls.into_iter().map(crate::Url::from).collect();
60
61 Self {
62 cutoff: raw.cutoff,
63 last_check,
64 num_checks: raw.num_checks,
65 check_frequency: raw.check_frequency,
66 urls,
67 version: raw.version,
68 }
69 }
70}