-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathyeasts.rs
92 lines (86 loc) · 2.97 KB
/
yeasts.rs
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
use rustybeer::conversions::ToMap;
pub use rustybeer::yeasts::{Criteria, Yeast, YEASTS};
use rweb::*;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Deserialize, Schema)]
pub struct YeastQuery {
/// Filter for producer, case insensitive
pub company: Option<String>,
/// Filter for yeast name, case insensitive
pub name: Option<String>,
/// Filter for yeast attenuation
pub attenuation: Option<u8>,
/// Filter for yeast optimal temperature
pub temperature: Option<String>,
}
// TODO: This is total copy of the yeast from rustybeer_util crate.
// If it's possible to find a way to reuse the same struct with different traits
// it should be done. But couldn't find a way.
#[derive(Debug, Serialize, Schema)]
pub struct YeastResponse {
/// Producer
pub company: String,
/// Name
pub name: String,
/// Id
pub id: Option<String>,
/// Minimum attenuation
pub min_attenuation: Option<u8>,
/// Maximum attenuation
pub max_attenuation: Option<u8>,
/// Attenuation level
pub attenuation_level: Option<String>,
/// Flocculation level
pub flocculation: Option<String>,
/// Minimum optimal temperature
pub min_temp: Option<HashMap<String, f64>>,
/// Maximum optimal temperature
pub max_temp: Option<HashMap<String, f64>>,
/// Alcohol tolerance
pub alc_tolerance: Option<u8>,
/// Alcohol tolerance level
pub alc_tolerance_level: Option<String>,
}
impl YeastResponse {
fn from_yeast(yeast: &Yeast) -> YeastResponse {
YeastResponse {
name: yeast.name.clone(),
company: yeast.company.clone(),
id: yeast.id.as_ref().map_or(None, |i| Some(i.to_string())),
min_attenuation: yeast.min_attenuation,
max_attenuation: yeast.max_attenuation,
attenuation_level: yeast
.attenuation_level
.map_or(None, |a| Some(a.to_string())),
flocculation: yeast.flocculation.map_or(None, |f| Some(f.to_string())),
min_temp: yeast.min_temp.map_or(None, |t| Some(t.to_map())),
max_temp: yeast.max_temp.map_or(None, |t| Some(t.to_map())),
alc_tolerance: yeast.alc_tolerance,
alc_tolerance_level: yeast
.alc_tolerance_level
.map_or(None, |a| Some(a.to_string())),
}
}
}
#[get("/yeasts")]
#[openapi(
id = "yeasts",
description = "Lists yeasts that match optional query parameters",
summary = "List yeasts"
)]
pub fn search(q: Query<YeastQuery>) -> Json<Vec<YeastResponse>> {
let query = q.into_inner();
let criteria = Criteria {
name: query.name,
company: query.company,
attenuation: query.attenuation,
temperature: query.temperature,
};
let resp: Vec<YeastResponse> = YEASTS
.iter()
.filter(|yeast| criteria.matches(yeast))
.map(|yeast| YeastResponse::from_yeast(&yeast))
.collect();
Json::from(resp)
}