From 0c7d55647e08cf8d66a498c73d5664e72bbcb03b Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sun, 4 Apr 2021 12:06:33 +0200 Subject: [PATCH] [#4] JSON requests now work! --- src/ivago/controller/pickup_times.rs | 48 +++++++++++++++++++++------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/ivago/controller/pickup_times.rs b/src/ivago/controller/pickup_times.rs index 174e538..58d3f29 100644 --- a/src/ivago/controller/pickup_times.rs +++ b/src/ivago/controller/pickup_times.rs @@ -7,7 +7,7 @@ use rocket::request::FromFormValue; use serde::ser::{SerializeStruct, Serializer}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use std::convert::From; +use std::convert::{From, TryFrom}; use std::error::Error; const BASE_URL: &str = "https://www.ivago.be/nl/particulier/afval/ophaling"; @@ -26,9 +26,29 @@ impl<'v> FromFormValue<'v> for BasicDate { fn from_form_value(form_value: &'v RawStr) -> Result { // Beautiful how this exact example is in the docs + match BasicDate::try_from(form_value.as_str()) { + Err(_) => Err(form_value), + // Here, we can assume these parses will work, because the regex + // didn't fail + Ok(date) => Ok(date), + } + } +} + +impl ToString for BasicDate { + fn to_string(&self) -> String { + format!("{}-{}-{}", self.year, self.month, self.day) + } +} + +impl TryFrom<&str> for BasicDate { + type Error = (); + + fn try_from(s: &str) -> Result { let re = Regex::new(r"^(\d{4})-(\d{2})-(\d{2})$").unwrap(); - match re.captures(form_value) { - None => Err(form_value), + + match re.captures(s) { + None => Err(()), // Here, we can assume these parses will work, because the regex // didn't fail Some(caps) => Ok(BasicDate { @@ -40,12 +60,6 @@ impl<'v> FromFormValue<'v> for BasicDate { } } -impl ToString for BasicDate { - fn to_string(&self) -> String { - format!("{}-{}-{}", self.year, self.month, self.day) - } -} - impl Serialize for BasicDate { fn serialize(&self, serializer: S) -> Result where @@ -82,7 +96,6 @@ impl Serialize for PickupTime { /// Represents a pickup time instance. All fields are a direct map of the /// original API -#[derive(Deserialize)] pub struct PickupTime { date: BasicDate, label: String, @@ -123,8 +136,19 @@ pub fn get_pickup_times( let mut output: Vec = Vec::new(); for map in data.iter() { - if let Some(value) = map.get("value") {} + output.push(PickupTime { + // TODO should I check here if the parsing worked? + date: BasicDate::try_from(map.get("date").unwrap().as_str()).unwrap(), + label: map.get("label").unwrap().to_string(), + classes: map + .get("classes") + .unwrap() + .split_whitespace() + .map(|x| String::from(x)) + .collect(), + url: map.get("url").unwrap().to_string(), + }) } - Ok() + Ok(output) }