-
Notifications
You must be signed in to change notification settings - Fork 0
/
day04.rs
103 lines (94 loc) · 2.87 KB
/
day04.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
93
94
95
96
97
98
99
100
101
102
103
use axum::{http::StatusCode, routing, Json, Router};
use ordered_float::OrderedFloat;
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
#[derive(Deserialize)]
struct Reindeer {
strength: u64,
// validate name even though we don't use it
// that way our API remains stable if we need it in the future
#[serde(rename = "name")]
_name: String,
}
async fn strength(Json(herd): Json<Vec<Reindeer>>) -> String {
herd.iter()
.map(|reindeer| reindeer.strength)
.sum::<u64>()
.to_string()
}
#[derive(Deserialize)]
struct ContestReindeer {
name: String,
strength: u64,
speed: f64,
height: u64,
antler_width: u64,
snow_magic_power: u64,
favorite_food: String,
#[serde(rename = "cAnD13s_3ATeN-yesT3rdAy")]
consumed: u64,
}
#[derive(Serialize)]
struct Summary {
fastest: String,
tallest: String,
magician: String,
consumer: String,
}
fn winners<'s>(
herd: &'s Vec<ContestReindeer>,
) -> Option<(
&'s ContestReindeer,
&'s ContestReindeer,
&'s ContestReindeer,
&'s ContestReindeer,
)> {
Some((
herd.iter()
.max_by_key(|reindeer| OrderedFloat(reindeer.speed))?,
herd.iter().max_by_key(|reindeer| reindeer.height)?,
herd.iter()
.max_by_key(|reindeer| reindeer.snow_magic_power)?,
herd.iter().max_by_key(|reindeer| reindeer.consumed)?,
))
}
impl Summary {
fn new(herd: &Vec<ContestReindeer>) -> Result<Self, (StatusCode, String)> {
let (fastest, tallest, magician, consumer) = winners(herd).ok_or((
StatusCode::BAD_REQUEST,
"need at least one reindeer".to_string(),
))?;
Ok(Summary {
fastest: format!(
"Speeding past the finish line with a strength of {strength} is {name}",
strength = fastest.strength,
name = fastest.name
),
tallest: format!(
"{name} is standing tall with his {antler_width} cm wide antlers",
name = tallest.name,
antler_width = tallest.antler_width,
),
magician: format!(
"{name} could blast you away with a snow magic power of {snow_magic_power}",
name = magician.name,
snow_magic_power = magician.snow_magic_power,
),
consumer: format!(
"{name} ate lots of candies, but also some {favorite_food}",
name = consumer.name,
favorite_food = consumer.favorite_food
),
})
}
}
async fn contest(
Json(herd): Json<Vec<ContestReindeer>>,
) -> Result<Json<Summary>, (StatusCode, String)> {
Ok(Json(Summary::new(&herd)?))
}
pub fn get_routes() -> Router<PgPool> {
Router::new()
.route("/4/strength", routing::post(strength))
.route("/4/contest", routing::post(contest))
}