mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 20:32:48 +00:00
Datetime ordering and chrono Weekdays
This commit is contained in:
@@ -72,6 +72,7 @@ derive_more = { version = "2.0", features = [
|
|||||||
"into",
|
"into",
|
||||||
"deref",
|
"deref",
|
||||||
"constructor",
|
"constructor",
|
||||||
|
"display",
|
||||||
] }
|
] }
|
||||||
askama = { version = "0.14", features = ["serde_json"] }
|
askama = { version = "0.14", features = ["serde_json"] }
|
||||||
askama_web = { version = "0.14.0", features = ["actix-web-4"] }
|
askama_web = { version = "0.14.0", features = ["actix-web-4"] }
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use super::{CalDateTime, CalDateTimeError};
|
use super::{CalDateTime, CalDateTimeError};
|
||||||
|
use chrono::Weekday;
|
||||||
use std::{num::ParseIntError, str::FromStr};
|
use std::{num::ParseIntError, str::FromStr};
|
||||||
use strum_macros::EnumString;
|
use strum_macros::EnumString;
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ pub enum RecurrenceFrequency {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, EnumString, PartialEq)]
|
#[derive(Debug, Clone, EnumString, PartialEq)]
|
||||||
#[strum(serialize_all = "UPPERCASE")]
|
#[strum(serialize_all = "UPPERCASE")]
|
||||||
pub enum Weekday {
|
pub enum IcalWeekday {
|
||||||
Mo,
|
Mo,
|
||||||
Tu,
|
Tu,
|
||||||
We,
|
We,
|
||||||
@@ -43,6 +44,20 @@ pub enum Weekday {
|
|||||||
Su,
|
Su,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<IcalWeekday> for Weekday {
|
||||||
|
fn from(value: IcalWeekday) -> Self {
|
||||||
|
match value {
|
||||||
|
IcalWeekday::Mo => Self::Mon,
|
||||||
|
IcalWeekday::Tu => Self::Tue,
|
||||||
|
IcalWeekday::We => Self::Wed,
|
||||||
|
IcalWeekday::Th => Self::Thu,
|
||||||
|
IcalWeekday::Fr => Self::Fri,
|
||||||
|
IcalWeekday::Sa => Self::Sat,
|
||||||
|
IcalWeekday::Su => Self::Sun,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum RecurrenceLimit {
|
pub enum RecurrenceLimit {
|
||||||
Count(usize),
|
Count(usize),
|
||||||
@@ -126,7 +141,8 @@ impl RecurrenceRule {
|
|||||||
.map(|val| {
|
.map(|val| {
|
||||||
assert!(val.len() >= 2);
|
assert!(val.len() >= 2);
|
||||||
let weekday =
|
let weekday =
|
||||||
Weekday::from_str(val.get((val.len() - 2)..).unwrap())?;
|
IcalWeekday::from_str(val.get((val.len() - 2)..).unwrap())?
|
||||||
|
.into();
|
||||||
let prefix = if val.len() > 2 {
|
let prefix = if val.len() > 2 {
|
||||||
Some(val.get(..(val.len() - 2)).unwrap().parse()?)
|
Some(val.get(..(val.len() - 2)).unwrap().parse()?)
|
||||||
} else {
|
} else {
|
||||||
@@ -165,7 +181,7 @@ impl RecurrenceRule {
|
|||||||
.collect::<Result<Vec<_>, _>>()?,
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
("WKST", val) => week_start = Some(Weekday::from_str(val)?),
|
("WKST", val) => week_start = Some(IcalWeekday::from_str(val)?.into()),
|
||||||
("BYSETPOS", val) => {
|
("BYSETPOS", val) => {
|
||||||
bysetpos = Some(
|
bysetpos = Some(
|
||||||
val.split(',')
|
val.split(',')
|
||||||
@@ -196,12 +212,12 @@ impl RecurrenceRule {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::{ParserError, RecurrenceRule};
|
||||||
use crate::{
|
use crate::{
|
||||||
CalDateTime,
|
CalDateTime,
|
||||||
rrule::{RecurrenceFrequency, RecurrenceLimit, Weekday},
|
rrule::{RecurrenceFrequency, RecurrenceLimit},
|
||||||
};
|
};
|
||||||
|
use chrono::Weekday;
|
||||||
use super::{ParserError, RecurrenceRule};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_recurrence_rule() -> Result<(), ParserError> {
|
fn parse_recurrence_rule() -> Result<(), ParserError> {
|
||||||
@@ -223,9 +239,9 @@ mod tests {
|
|||||||
limit: Some(RecurrenceLimit::Count(4)),
|
limit: Some(RecurrenceLimit::Count(4)),
|
||||||
interval: 2,
|
interval: 2,
|
||||||
byday: Some(vec![
|
byday: Some(vec![
|
||||||
(None, Weekday::Tu),
|
(None, Weekday::Tue),
|
||||||
(None, Weekday::Th),
|
(None, Weekday::Thu),
|
||||||
(None, Weekday::Su),
|
(None, Weekday::Sun),
|
||||||
]),
|
]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
@@ -236,11 +252,11 @@ mod tests {
|
|||||||
RecurrenceRule {
|
RecurrenceRule {
|
||||||
frequency: RecurrenceFrequency::Monthly,
|
frequency: RecurrenceFrequency::Monthly,
|
||||||
byday: Some(vec![
|
byday: Some(vec![
|
||||||
(None, Weekday::Mo),
|
(None, Weekday::Mon),
|
||||||
(None, Weekday::Tu),
|
(None, Weekday::Tue),
|
||||||
(None, Weekday::We),
|
(None, Weekday::Wed),
|
||||||
(None, Weekday::Th),
|
(None, Weekday::Thu),
|
||||||
(None, Weekday::Fr),
|
(None, Weekday::Fri),
|
||||||
]),
|
]),
|
||||||
bysetpos: Some(vec![-1]),
|
bysetpos: Some(vec![-1]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -255,7 +271,7 @@ mod tests {
|
|||||||
limit: Some(RecurrenceLimit::Until(
|
limit: Some(RecurrenceLimit::Until(
|
||||||
CalDateTime::parse("20370329T010000Z", None).unwrap()
|
CalDateTime::parse("20370329T010000Z", None).unwrap()
|
||||||
)),
|
)),
|
||||||
byday: Some(vec![(Some(-1), Weekday::Su)]),
|
byday: Some(vec![(Some(-1), Weekday::Sun)]),
|
||||||
bymonth: Some(vec![3]),
|
bymonth: Some(vec![3]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ impl ValueSerialize for UtcDateTime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
|
||||||
pub enum CalDateTime {
|
pub enum CalDateTime {
|
||||||
// Form 1, example: 19980118T230000 -> Local
|
// Form 1, example: 19980118T230000 -> Local
|
||||||
// Form 2, example: 19980119T070000Z -> UTC
|
// Form 2, example: 19980119T070000Z -> UTC
|
||||||
@@ -256,84 +256,72 @@ impl Datelike for CalDateTime {
|
|||||||
CalDateTime::Date(date) => date.month0(),
|
CalDateTime::Date(date) => date.month0(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn day(&self) -> u32 {
|
fn day(&self) -> u32 {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => datetime.day(),
|
CalDateTime::DateTime(datetime) => datetime.day(),
|
||||||
CalDateTime::Date(date) => date.day(),
|
CalDateTime::Date(date) => date.day(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn day0(&self) -> u32 {
|
fn day0(&self) -> u32 {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => datetime.day0(),
|
CalDateTime::DateTime(datetime) => datetime.day0(),
|
||||||
CalDateTime::Date(date) => date.day0(),
|
CalDateTime::Date(date) => date.day0(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ordinal(&self) -> u32 {
|
fn ordinal(&self) -> u32 {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => datetime.ordinal(),
|
CalDateTime::DateTime(datetime) => datetime.ordinal(),
|
||||||
CalDateTime::Date(date) => date.ordinal(),
|
CalDateTime::Date(date) => date.ordinal(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ordinal0(&self) -> u32 {
|
fn ordinal0(&self) -> u32 {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => datetime.ordinal0(),
|
CalDateTime::DateTime(datetime) => datetime.ordinal0(),
|
||||||
CalDateTime::Date(date) => date.ordinal0(),
|
CalDateTime::Date(date) => date.ordinal0(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn weekday(&self) -> chrono::Weekday {
|
fn weekday(&self) -> chrono::Weekday {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => datetime.weekday(),
|
CalDateTime::DateTime(datetime) => datetime.weekday(),
|
||||||
CalDateTime::Date(date) => date.weekday(),
|
CalDateTime::Date(date) => date.weekday(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iso_week(&self) -> chrono::IsoWeek {
|
fn iso_week(&self) -> chrono::IsoWeek {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => datetime.iso_week(),
|
CalDateTime::DateTime(datetime) => datetime.iso_week(),
|
||||||
CalDateTime::Date(date) => date.iso_week(),
|
CalDateTime::Date(date) => date.iso_week(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_year(&self, year: i32) -> Option<Self> {
|
fn with_year(&self, year: i32) -> Option<Self> {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_year(year)?)),
|
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_year(year)?)),
|
||||||
CalDateTime::Date(date) => Some(Self::Date(date.with_year(year)?)),
|
CalDateTime::Date(date) => Some(Self::Date(date.with_year(year)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_month(&self, month: u32) -> Option<Self> {
|
fn with_month(&self, month: u32) -> Option<Self> {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_month(month)?)),
|
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_month(month)?)),
|
||||||
CalDateTime::Date(date) => Some(Self::Date(date.with_month(month)?)),
|
CalDateTime::Date(date) => Some(Self::Date(date.with_month(month)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_month0(&self, month0: u32) -> Option<Self> {
|
fn with_month0(&self, month0: u32) -> Option<Self> {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_month0(month0)?)),
|
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_month0(month0)?)),
|
||||||
CalDateTime::Date(date) => Some(Self::Date(date.with_month0(month0)?)),
|
CalDateTime::Date(date) => Some(Self::Date(date.with_month0(month0)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_day(&self, day: u32) -> Option<Self> {
|
fn with_day(&self, day: u32) -> Option<Self> {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_day(day)?)),
|
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_day(day)?)),
|
||||||
CalDateTime::Date(date) => Some(Self::Date(date.with_day(day)?)),
|
CalDateTime::Date(date) => Some(Self::Date(date.with_day(day)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_day0(&self, day0: u32) -> Option<Self> {
|
fn with_day0(&self, day0: u32) -> Option<Self> {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_day0(day0)?)),
|
CalDateTime::DateTime(datetime) => Some(Self::DateTime(datetime.with_day0(day0)?)),
|
||||||
CalDateTime::Date(date) => Some(Self::Date(date.with_day0(day0)?)),
|
CalDateTime::Date(date) => Some(Self::Date(date.with_day0(day0)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_ordinal(&self, ordinal: u32) -> Option<Self> {
|
fn with_ordinal(&self, ordinal: u32) -> Option<Self> {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => {
|
CalDateTime::DateTime(datetime) => {
|
||||||
@@ -342,7 +330,6 @@ impl Datelike for CalDateTime {
|
|||||||
CalDateTime::Date(date) => Some(Self::Date(date.with_ordinal(ordinal)?)),
|
CalDateTime::Date(date) => Some(Self::Date(date.with_ordinal(ordinal)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_ordinal0(&self, ordinal0: u32) -> Option<Self> {
|
fn with_ordinal0(&self, ordinal0: u32) -> Option<Self> {
|
||||||
match &self {
|
match &self {
|
||||||
CalDateTime::DateTime(datetime) => {
|
CalDateTime::DateTime(datetime) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user