From f58c120bcc0a84156e5e253be57c1f958ea8576e Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 27 Feb 2022 09:36:14 +0100 Subject: Don’t create an event if repetition is not valid --- README.md | 10 ++-------- src/gui/form/mod.rs | 26 +++++++++++++++----------- src/gui/form/repetition.rs | 23 ++++++++++------------- src/model/repetition.rs | 20 +++++++++++++++----- 4 files changed, 42 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 2986378..e52d48c 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,8 @@ cargo test ## V1 -### Repeat events - -1. When validating repetition, don’t produce None if there is a validation error. -2. Update / delete specific repetition occurences. - -### Navigate around - -1. Select previous or next week with shortcuts. +- Select previous or next week with shortcuts. +- Update / delete specific repetition occurences. ## V2 diff --git a/src/gui/form/mod.rs b/src/gui/form/mod.rs index 4bf6f90..57ccac7 100644 --- a/src/gui/form/mod.rs +++ b/src/gui/form/mod.rs @@ -81,19 +81,23 @@ pub async fn show(app: &App, event: Event, is_new: bool) { let conn = app.conn.clone(); let tx = app.tx.clone(); button.connect_clicked(glib::clone!(@weak dialog, @strong event => move |_| { - let repetition = repetition::validate(&repetition_model); - match event::validate(event.id, date.buffer().text(), name.buffer().text(), start.buffer().text(), end.buffer().text(), repetition) { - Some(new) => { - match if is_new { db::insert(&conn, &new) } else { db::update(&conn, &new) } { - Ok(_) => { - let msg = if is_new { Msg::AddEvent { new } } else { Msg::UpdateEvent { old: event.clone(), new } }; - update::send(tx.clone(), msg); - dialog.close() - }, - Err(err) => eprintln!("Error when upserting event: {err}") + match repetition::validate(&repetition_model) { + Ok(repetition) => { + match event::validate(event.id, date.buffer().text(), name.buffer().text(), start.buffer().text(), end.buffer().text(), repetition) { + Some(new) => { + match if is_new { db::insert(&conn, &new) } else { db::update(&conn, &new) } { + Ok(_) => { + let msg = if is_new { Msg::AddEvent { new } } else { Msg::UpdateEvent { old: event.clone(), new } }; + update::send(tx.clone(), msg); + dialog.close() + }, + Err(err) => eprintln!("Error when upserting event: {err}") + } + } + None => eprintln!("Event is not valid: {event:?}") } }, - None => eprintln!("Event is not valid: {event:?}") + Err(message) => eprintln!("{message}") } })); diff --git a/src/gui/form/repetition.rs b/src/gui/form/repetition.rs index 87c8d84..7236016 100644 --- a/src/gui/form/repetition.rs +++ b/src/gui/form/repetition.rs @@ -126,26 +126,23 @@ fn label(text: &str) -> gtk::Label { .build() } -pub fn validate(model: &Model) -> Option { +pub fn validate(model: &Model) -> Result, String> { if model.no_radio.is_active() { - None + Ok(None) } else if model.day_interval_radio.is_active() { - repetition::validate_day(&model.day_interval_entry.buffer().text()) - .map(|d| Repetition::Daily { period: d }) + let period = repetition::validate_period(&model.day_interval_entry.buffer().text())?; + Ok(Some(Repetition::Daily { period })) } else if model.monthly_radio.is_active() { - repetition::validate_day(&model.monthly_entry.buffer().text()).map(|d| { - Repetition::Monthly { - day: DayOfMonth::Day { day: d }, - } - }) + let day = repetition::validate_day(&model.monthly_entry.buffer().text())?; + Ok(Some(Repetition::Monthly { day: DayOfMonth::Day { day } })) } else if model.first_day_radio.is_active() { let weekday = WEEKDAYS[model.first_day_dropdown.selected() as usize]; - Some(Repetition::Monthly { + Ok(Some(Repetition::Monthly { day: DayOfMonth::Weekday { weekday }, - }) + })) } else if model.yearly_radio.is_active() { - Some(Repetition::Yearly) + Ok(Some(Repetition::Yearly)) } else { - None + Err("Aucune option n’a été sélectionnée".to_string()) } } diff --git a/src/model/repetition.rs b/src/model/repetition.rs index d21dd70..5288358 100644 --- a/src/model/repetition.rs +++ b/src/model/repetition.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum Repetition { - Daily { period: u8 }, + Daily { period: u32 }, Monthly { day: DayOfMonth }, Yearly, } @@ -14,12 +14,22 @@ pub enum DayOfMonth { Weekday { weekday: Weekday }, } -pub fn validate_day(str: &str) -> Option { - let n = str.parse::().ok()?; +pub fn validate_period(str: &str) -> Result { + let n = str.parse::().map_err(|_| format!("{} n’est pas une période valide.", str))?; + if n == 0 { + Err("La periode doit être positive.".to_string()) + } else { + Ok(n) + } +} + + +pub fn validate_day(str: &str) -> Result { + let n = str.parse::().map_err(|_| format!("« {} » n’est pas un jour valide.", str))?; if (1..=31).contains(&n) { - Some(n) + Ok(n) } else { - None + Err("Le jour devrait se situer entre le 1er et le 31 du mois.".to_string()) } } -- cgit v1.2.3