1pub type Result<T = ()> = std::result::Result<T, reqwest::Error>;
2
3#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, serde::Deserialize)]
4pub enum Scale {
5 #[default]
6 #[serde(rename = "H")]
7 Level,
8 #[serde(rename = "Q")]
9 Flow,
10}
11
12impl std::fmt::Display for Scale {
13 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 let s = match self {
15 Self::Flow => "Q",
16 Self::Level => "H",
17 };
18
19 f.write_str(s)
20 }
21}
22
23#[derive(Debug, Clone, serde::Deserialize)]
24#[serde(rename_all = "PascalCase")]
25pub struct Data {
26 #[serde(rename = "VersionFlux")]
27 pub version: String,
28 pub serie: Serie,
29}
30
31#[derive(Debug, Clone, serde::Deserialize)]
32#[serde(rename_all = "PascalCase")]
33pub struct Serie {
34 #[serde(rename = "CdStationHydro")]
35 pub code_station: String,
36 #[serde(rename = "LbStationHydro")]
37 pub label_station: String,
38 pub link: String,
39 #[serde(rename = "GrdSerie")]
40 pub scale: Scale,
41 #[serde(rename = "ObssHydro")]
42 pub mesures: Vec<Mesure>,
43}
44
45#[derive(Debug, Clone, serde::Deserialize)]
46#[serde(rename_all = "PascalCase")]
47pub struct Mesure {
48 #[serde(rename = "DtObsHydro", deserialize_with = "de_js_datetime")]
49 pub date: chrono::NaiveDateTime,
50 #[serde(rename = "ResObsHydro")]
51 pub mesure: f32,
52}
53
54fn de_js_datetime<'de, D>(deserializer: D) -> std::result::Result<chrono::NaiveDateTime, D::Error>
55where
56 D: serde::Deserializer<'de>,
57{
58 let timestamp = serde::Deserialize::deserialize(deserializer)?;
59
60 Ok(chrono::NaiveDateTime::from_timestamp_millis(timestamp).unwrap())
61}
62
63pub async fn level(station: &str) -> Result<Data> {
64 fetch(station, Scale::Level).await
65}
66
67pub async fn flow(station: &str) -> Result<Data> {
68 fetch(station, Scale::Flow).await
69}
70
71async fn fetch(station: &str, scale: Scale) -> Result<Data> {
72 let url = format!("https://www.vigicrues.gouv.fr/services/observations.json/index.php?CdStationHydro={station}&GrdSerie={scale}");
73
74 reqwest::get(&url).await?.json().await
75}