use std::result::Result as RResult; use curl::easy::Easy2; use crate::v1::error::Result; use crate::v1::error::RepologyError as Error; use crate::v1::types::{Package, Problem}; use crate::v1::api::Api; /// Private helper type for collecting data from the curl library struct Collector(Vec); impl curl::easy::Handler for Collector { fn write(&mut self, data: &[u8]) -> RResult { self.0.extend_from_slice(data); Ok(data.len()) } } /// Representational object for the REST Api of repology pub struct RestApi { /// Base url repology: String, } impl RestApi { pub fn new(repology: String) -> Self { Self { repology } } /// Helper function for sending a request via the curl library fn send_request>(&self, request: U) -> Result { let mut easy = Easy2::new(Collector(Vec::new())); easy.get(true)?; easy.url(request.as_ref())?; easy.perform()?; let content = easy.get_ref().0.clone(); // TODO: Ugh... String::from_utf8(content).map_err(Error::from) } } impl Api for RestApi { fn project>(&self, name: N) -> Result> { let url = format!("{}api/v1/project/{}", self.repology, name.as_ref()); trace!("Request: {}", url); let response = self.send_request(url)?; serde_json::from_str(&response) .map_err(Error::from) } fn problems_for_repo>(&self, repo: R) -> Result> { let url = format!("{}api/v1/repository/{}/problems", self.repology, repo.as_ref()); trace!("Request: {}", url); let response = self.send_request(url)?; serde_json::from_str(&response).map_err(Error::from) } fn problems_for_maintainer>(&self, maintainer: M) -> Result> { let url = format!("{}api/v1/maintainer/{}/problems", self.repology, maintainer.as_ref()); trace!("Request: {}", url); let response = self.send_request(url)?; serde_json::from_str(&response).map_err(Error::from) } }