diff --git a/migrations/demo.sql b/migrations/demo.sql index 8eb0d76..73b2d4b 100644 --- a/migrations/demo.sql +++ b/migrations/demo.sql @@ -1,5 +1,5 @@ insert into contacts(id, birthday, manually_freshened_at) values - (0, '--0415', '2000-01-01T12:00:00'); + (0, '04-15', '2000-01-01T12:00:00'); insert into names(contact_id, sort, name) values (0, 0, 'Alex Aaronson'), (0, 1, 'Alexi'), @@ -16,7 +16,7 @@ insert into groups(contact_id, name, slug) values (1, 'ABC', 'abc'); insert into contacts(id, birthday) values - (2, '19951018'); + (2, '1995-10-18'); insert into names(contact_id, sort, name) values (2, 0, 'Charlie Certaindate'); insert into groups(contact_id, name, slug) values diff --git a/migrations/each_user/0014_birthday-format.sql b/migrations/each_user/0014_birthday-format.sql new file mode 100644 index 0000000..80b69cf --- /dev/null +++ b/migrations/each_user/0014_birthday-format.sql @@ -0,0 +1,7 @@ +update contacts + set birthday = substr(birthday, 3, 2) || '-' || substr(birthday, 5, 2) + where birthday GLOB '--[01][0-9][0-3][0-9]'; + +update contacts + set birthday = substr(birthday, 1, 4) || '-' || substr(birthday, 5, 2) || '-' || substr(birthday, 7, 2) + where birthday GLOB '[0-9][0-9][0-9][0-9][01][0-9][0-3][0-9]'; diff --git a/src/models/year_optional_date.rs b/src/models/year_optional_date.rs index d0052b8..a4cd381 100644 --- a/src/models/year_optional_date.rs +++ b/src/models/year_optional_date.rs @@ -57,21 +57,18 @@ impl Display for YearOptionalDate { impl FromStr for YearOptionalDate { type Err = anyhow::Error; fn from_str(str: &str) -> Result { - let date_re = Regex::new(r"^([0-9]{4}|--)([0-9]{2})([0-9]{2})$").unwrap(); + let date_re = Regex::new(r"^(?:([0-9]{4})-)?([0-9]{2})-([0-9]{2})$").unwrap(); if let Some(caps) = date_re.captures(str) { - let year_str = &caps[1]; + let year = caps + .get(1) + .map(|yyyy| i16::from_str(yyyy.as_str()).unwrap()); let month = i8::from_str(&caps[2]).unwrap(); let day = i8::from_str(&caps[3]).unwrap(); - let year = if year_str == "--" { - None - } else { - Some(i16::from_str(year_str).unwrap()) - }; return Ok(Self { year, month, day }); } Err(anyhow::Error::msg(format!( - "parsing failure in YearOptionalDate: '{}' does not match regex /([0-9]{{4}}|--)[0-9]{{4}}/", + "parsing failure in YearOptionalDate: '{}' does not match regex /([0-9]{{4}}-)?[0-9]{{2}}-[0-9]{{2}}/", str ))) } diff --git a/src/web/contact/mod.rs b/src/web/contact/mod.rs index 7dc487b..b99abdb 100644 --- a/src/web/contact/mod.rs +++ b/src/web/contact/mod.rs @@ -278,10 +278,10 @@ mod get { input name="periodicity" id="periodicity" value=(format!("{:#}", contact.periodicity)); span .hint { code { "[0-9]+ (yr|mo|wk|day|h|m|s)" } "(" a href="https://docs.rs/jiff/latest/jiff/struct.Span.html#parsing-and-printing" { "details" } ")" } } - label { "birthday" } + label for="birthday" { "birthday" } div { - input name="birthday" value=(contact.birthday.clone().map_or("".to_string(), |b| b.serialize())); - span .hint { code { "(yyyy|--)mmdd" } " or free text" } + input name="birthday" id="birthday" value=(contact.birthday.clone().map_or("".to_string(), |b| format!("{b}"))); + span .hint { code { "(yyyy-)?mm-dd" } " or free text" } } label for="manually_freshened_on" { "freshened" } div x-data=(json!({ "date": mfresh_on_str, "stamp": mfresh_at_str })) x-init="today = () => (new Date().toISOString().split('T')[0])" {