From a3e5ca2af35407db5fcc38b1552663e27e8029e7 Mon Sep 17 00:00:00 2001 From: Astro Date: Sat, 26 Oct 2019 02:19:33 +0200 Subject: [PATCH] ticker-serve: group_by_day() --- ticker-serve/src/main.rs | 83 +++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/ticker-serve/src/main.rs b/ticker-serve/src/main.rs index 97dbd68..9a6e4e4 100644 --- a/ticker-serve/src/main.rs +++ b/ticker-serve/src/main.rs @@ -1,13 +1,12 @@ #![feature(proc_macro_hygiene, decl_macro)] -#![recursion_limit="512"] +#![recursion_limit="1024"] -use std::fs::read_to_string; use std::sync::Mutex; #[macro_use] extern crate rocket; use rocket::{State, response::content}; use typed_html::{html, text, dom::DOMTree}; use diesel::{Connection, pg::PgConnection, prelude::*}; -use chrono::offset::Local; +use chrono::{offset::Local, NaiveDate}; use libticker::{ config::{Config, CalendarOptions}, @@ -24,6 +23,33 @@ fn fix_url(s: &str) -> std::borrow::Cow { } } +struct DayEvents<'e> { + date: NaiveDate, + events: &'e [Event], +} + +/// assumes pre-sorted input +fn group_by_day(es: &[Event]) -> Vec { + let mut results = vec![]; + + let mut prev_date = None; + let mut date_start = 0; + for (i, event) in es.iter().enumerate() { + if prev_date.is_some() && prev_date != Some(event.dtstart.date()) { + if i > date_start { + results.push(DayEvents { + date: prev_date.unwrap().clone(), + events: &es[date_start..i], + }); + date_start = i; + } + } + prev_date = Some(event.dtstart.date()); + } + + results +} + #[get("/")] fn index(db: State>) -> content::Html { let db = db.lock().unwrap(); @@ -34,7 +60,8 @@ fn index(db: State>) -> content::Html { .then_order_by(schema::events::dtend.desc()) .load::(&*db) .unwrap(); - + let days = group_by_day(&es); + let doc: DOMTree = html!( @@ -43,29 +70,33 @@ fn index(db: State>) -> content::Html {

"Ticker"

- { es.iter().map(|e| html!( -
- { match &e.url { - None => html!( -

{ text!("{}", &e.summary) }

- ), - Some(url) => html!( -

- - { text!("{}", &e.summary) } - -

- ), - } } + { days.iter().map(|day| html!(
+ -

{ text!("{}", &e.dtstart) }

- { e.location.as_ref().map(|location| html!( -

- { text!("{}", location) } -

- )) } -
- )) } + { day.events.iter().map(|e| html!( +
+ { match &e.url { + None => html!( +

{ text!("{}", &e.summary) }

+ ), + Some(url) => html!( +

+ + { text!("{}", &e.summary) } + +

+ ), + } } + +

{ text!("{}", &e.dtstart) }

+ { e.location.as_ref().map(|location| html!( +

+ { text!("{}", location) } +

+ )) } +
+ )) } + )) } );