Skip to main content

vigicrues/
lib.rs

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}