-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
day12.rs
95 lines (88 loc) · 2.53 KB
/
day12.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
use axum::{
extract::{Path, State},
http::StatusCode,
response::IntoResponse,
routing::{get, post},
Json, Router,
};
use chrono::{DateTime, Datelike, Utc};
use std::{
collections::HashMap,
sync::{Arc, Mutex},
time::SystemTime,
};
struct Day12State {
times: HashMap<String, SystemTime>,
}
pub(crate) fn router() -> Router {
Router::new()
.route("/12/save/:string", post(save))
.route("/12/load/:string", get(load))
.route("/12/ulids", post(ulids))
.route("/12/ulids/:weekday", post(ulids_weekday))
.with_state(Arc::new(Mutex::new(Day12State {
times: HashMap::new(),
})))
}
async fn save(State(state): State<Arc<Mutex<Day12State>>>, Path(string): Path<String>) {
state
.lock()
.expect("Should not error unless another thread panics")
.times
.insert(string, SystemTime::now());
}
async fn load(
State(state): State<Arc<Mutex<Day12State>>>,
Path(string): Path<String>,
) -> Result<impl IntoResponse, (StatusCode, String)> {
Ok(state
.lock()
.expect("Should not error unless another thread panics")
.times
.get(&string)
.ok_or((
StatusCode::NOT_FOUND,
"String not saved previously".to_string(),
))?
.elapsed()
.expect("Time should not go backwards")
.as_secs()
.to_string())
}
async fn ulids(Json(ulids): Json<Vec<ulid::Ulid>>) -> Json<Vec<uuid::Uuid>> {
Json(ulids.into_iter().map(Into::into).rev().collect())
}
#[derive(serde::Serialize)]
struct UlidsWeekday {
#[serde(rename = "christmas eve")]
christmas_eve: usize,
weekday: usize,
#[serde(rename = "in the future")]
in_the_future: usize,
#[serde(rename = "LSB is 1")]
lsb_is_1: usize,
}
#[axum::debug_handler]
async fn ulids_weekday(
Path(weekday): Path<u32>,
Json(ulids): Json<Vec<ulid::Ulid>>,
) -> Json<UlidsWeekday> {
let lsb_is_1 = ulids.iter().filter(|u| u.random() & 1 == 1).count();
let ulids: Vec<DateTime<Utc>> = ulids.into_iter().map(|u| u.datetime().into()).collect();
let christmas_eve = ulids
.iter()
.filter(|u| u.month() == 12 && u.day() == 24)
.count();
let weekday = ulids
.iter()
.filter(|u| u.weekday().num_days_from_monday() == weekday)
.count();
let now = Utc::now();
let in_the_future = ulids.iter().filter(|&u| u > &now).count();
Json(UlidsWeekday {
christmas_eve,
weekday,
in_the_future,
lsb_is_1,
})
}