1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::{Error, FromElement, Meal, Update};
use serde::{Serialize, Deserialize};
use chrono;
use scraper;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Day {
pub date: chrono::NaiveDate,
pub meals: Vec<Meal>,
pub side_dishes: Vec<String>,
}
impl FromElement for Day {
type Err = Error;
fn from_element(day_node: &scraper::ElementRef) -> Result<Self, Self::Err> {
let date = day_node
.select(&ovgu_canteen_selector![date])
.next()
.and_then(|node| node.text().next())
.ok_or(Error::NotAvailable { member: "date", object: "day" })
.and_then(|date_str| {
chrono::NaiveDate::parse_from_str(&date_str[date_str.len() - 10..], "%d.%m.%Y")
.map_err(|e| Error::InvalidValue {
member: "date",
object: "day",
cause: Box::new(e),
})
})?;
let meals = day_node
.select(&ovgu_canteen_selector![meal])
.map(|meal_node| Meal::from_element(&meal_node))
.filter_map(|res| res.ok())
.collect::<Vec<Meal>>();
let side_dishes = day_node
.select(&ovgu_canteen_selector![side_dishes])
.next()
.and_then(|node| node.text().next())
.map(|side_dishes_str| {
side_dishes_str[10..]
.trim()
.split(", ")
.map(|s| s.to_string())
.collect()
})
.unwrap_or(vec![]);
Ok(Day {
date: date,
meals: meals,
side_dishes: side_dishes,
})
}
}
impl Update for Day {
type Err = Error;
fn update(&mut self, from: &Self) -> Result<(), Self::Err> {
for meal in from.meals.iter() {
if match self.meals.iter_mut().find(|m| *m == meal) {
Some(ref mut m) => {
m.update(meal)?;
false
}
None => true,
}
{
self.meals.push(meal.clone());
}
}
for side_dish in from.side_dishes.iter() {
if !self.side_dishes.contains(side_dish) {
self.side_dishes.push(side_dish.clone());
}
}
Ok(())
}
}
impl PartialEq for Day {
fn eq(&self, other: &Self) -> bool {
self.date == other.date
}
}