diff --git a/affluences-api/src/models/available.rs b/affluences-api/src/models/available.rs index dd0980a..29df5c5 100644 --- a/affluences-api/src/models/available.rs +++ b/affluences-api/src/models/available.rs @@ -44,28 +44,25 @@ pub struct Resource { impl Resource { pub fn condensed_hours(&self) -> Vec<(&HourBlock, Duration)> { - let mut start_hour_opt: Option<&HourBlock> = None; - let mut duration = Duration::seconds(0); + if self.hours.is_empty() { + return Default::default(); + } + + let mut start_hour = self.hours.first().unwrap(); + let mut duration = Duration::minutes(start_hour.granularity.into()); let mut out: Vec<(&HourBlock, Duration)> = Default::default(); - for hour in &self.hours { - if let Some(start_hour) = start_hour_opt { - if hour.state == start_hour.state { - duration = duration + Duration::minutes(hour.granularity.into()); - } else { - out.push((start_hour, duration)); - start_hour_opt = Some(hour); - duration = Duration::minutes(hour.granularity.into()); - } - } else if hour.state == 1 { - start_hour_opt = Some(hour); + for hour in self.hours.iter().skip(1) { + if hour.state == start_hour.state { + duration = duration + Duration::minutes(hour.granularity.into()); + } else { + out.push((start_hour, duration)); + start_hour = &hour; duration = Duration::minutes(hour.granularity.into()); } } - if let Some(start_hour) = start_hour_opt { - out.push((start_hour, duration)); - } + out.push((start_hour, duration)); out } diff --git a/src/commands/affluence.rs b/src/commands/affluence.rs index 60b8730..47d5f9b 100644 --- a/src/commands/affluence.rs +++ b/src/commands/affluence.rs @@ -1,32 +1,24 @@ +use crate::commands::EmbedField; use crate::{Context, Error}; +use affluences_api::Resource; use chrono::NaiveDate; use uuid::{uuid, Uuid}; const STERRE_BIB_ID: Uuid = uuid!("4737e57a-ee05-4f7b-901a-7bb541eeb297"); const TIME_FORMAT: &str = "%H:%M"; -/// List available timeslots for day -#[poise::command(prefix_command, slash_command)] -pub async fn available(ctx: Context<'_>, date: NaiveDate) -> Result<(), Error> { - let client = &ctx.data().client; - let resources = client.available(STERRE_BIB_ID, date, 1).await?; - let mut fields: Vec<(String, String, bool)> = Default::default(); +fn resource_to_embed_field(resource: Resource) -> EmbedField { + let available_hours = resource.condensed_available_hours(); - for resource in &resources { - let available_hours = resource.condensed_available_hours(); - - if available_hours.is_empty() { - fields.push(( - resource.resource_name.clone(), - "Nothing available.".to_string(), - false, - )); - - continue; - } - - fields.push(( + if available_hours.is_empty() { + ( + resource.resource_name.clone(), + "Nothing available.".to_string(), + false, + ) + } else { + ( resource.resource_name.clone(), available_hours .into_iter() @@ -42,13 +34,25 @@ pub async fn available(ctx: Context<'_>, date: NaiveDate) -> Result<(), Error> { .collect::>() .join("\n"), false, - )); + ) } +} + +/// List available timeslots for day +#[poise::command(prefix_command, slash_command)] +pub async fn available(ctx: Context<'_>, date: NaiveDate) -> Result<(), Error> { + let client = &ctx.data().client; + let resources = client.available(STERRE_BIB_ID, date, 1).await?; ctx.send(|f| { f.embed(|e| { e.description(format!("Available booking dates for {}.", date)) - .fields(fields) + .fields( + resources + .into_iter() + .map(resource_to_embed_field) + .collect::>(), + ) }) }) .await?; diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 24ca959..70a5dea 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -3,6 +3,8 @@ mod minecraft; use crate::{Context, Data, Error}; +type EmbedField = (String, String, bool); + pub fn commands() -> Vec> { vec![help(), affluence::available(), minecraft::ping_mc()] }