/* oslobike - find free bikes in Oslo. Copyright (C) 2019 Harald Eilertsen This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ use reqwest::{ self, header::{ HeaderMap, HeaderValue, }, Client, }; use crate::station::{ Station, StationAvailability, StationAvailabilityContainer, StationContainer }; use crate::error::ApiResult; const API_BASE: &'static str = "https://oslobysykkel.no/api/v1"; fn url_for(endpoint: &str) -> String { [API_BASE, endpoint].join("/") } /// The oslobike::Api struct holds the state for the Api. pub struct Api { client: reqwest::Client, } impl Api { /// Create an instance of the API like this: /// /// # let my_api_key = String::from("1234"); /// let api = oslobike::Api::new(my_api_key).expect("An error occured"); /// pub fn new(api_key: String) -> ApiResult { let mut hdrs = HeaderMap::new(); hdrs.insert("client-identifier", HeaderValue::from_str(&api_key)?); let client = Client::builder() .default_headers(hdrs) .build()?; Ok(Api { client }) } /// Fetch the list of stations and their basic data from the api. pub fn stations(&self) -> ApiResult> { let response_json = self.get("stations")?; let v: StationContainer = serde_json::from_str(&response_json)?; Ok(v.stations) } /// Fetch availability status for all stations pub fn station_availability(&self) -> ApiResult> { let response_json = self.get("stations/availability")?; let v: StationAvailabilityContainer = serde_json::from_str(&response_json)?; Ok(v.stations) } /// A helper method to fetch payloads from the upstream API fn get(&self, path: &str) -> ApiResult { self.client .get(&url_for(path)) .send()? .error_for_status()? .text() .map_err(crate::error::Error::ReqwestError) } }