mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 21:42:34 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53f30fce3f | ||
|
|
4592afac10 | ||
|
|
e7ab7c2987 | ||
|
|
242f7b9076 | ||
|
|
cb1356acad | ||
|
|
55dadbb06b | ||
|
|
4dd12bfe52 | ||
|
|
5e004a6edc | ||
|
|
03e550c2f8 |
239
Cargo.lock
generated
239
Cargo.lock
generated
@@ -242,11 +242,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca"
|
||||
checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"futures-io",
|
||||
@@ -255,7 +255,7 @@ dependencies = [
|
||||
"polling",
|
||||
"rustix",
|
||||
"slab",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -534,9 +534,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.36"
|
||||
version = "1.2.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54"
|
||||
checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
@@ -1288,7 +1288,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi 0.14.5+wasi-0.2.4",
|
||||
"wasi 0.14.7+wasi-0.2.4",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
@@ -1339,7 +1339,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http",
|
||||
"indexmap 2.11.1",
|
||||
"indexmap 2.11.4",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@@ -1363,6 +1363,12 @@ dependencies = [
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.10.0"
|
||||
@@ -1551,9 +1557,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.16"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
|
||||
checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
@@ -1575,9 +1581,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.63"
|
||||
version = "0.1.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
|
||||
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
@@ -1600,7 +1606,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ical"
|
||||
version = "0.11.0"
|
||||
source = "git+https://github.com/lennart-k/ical-rs#9035f46cd1d9d0a42e9727914301edc32bbcc126"
|
||||
source = "git+https://github.com/lennart-k/ical-rs#38e4201d5f653b07c9800cccec93996f542267b4"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
@@ -1737,13 +1743,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.11.1"
|
||||
version = "2.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921"
|
||||
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.5",
|
||||
"hashbrown 0.16.0",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1811,9 +1818,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.78"
|
||||
version = "0.3.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738"
|
||||
checksum = "852f13bec5eba4ba9afbeb93fd7c13fe56147f055939ae21c43a29a0ecb2702e"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
@@ -1851,9 +1858,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
|
||||
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
@@ -2498,16 +2505,16 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "3.10.0"
|
||||
version = "3.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829"
|
||||
checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"hermit-abi",
|
||||
"pin-project-lite",
|
||||
"rustix",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2545,11 +2552,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.3.0"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35"
|
||||
checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
|
||||
dependencies = [
|
||||
"toml_edit",
|
||||
"toml_edit 0.23.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3017,7 +3024,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -3048,7 +3055,7 @@ dependencies = [
|
||||
"serde",
|
||||
"sqlx",
|
||||
"tokio",
|
||||
"toml 0.9.5",
|
||||
"toml 0.9.7",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower-sessions",
|
||||
@@ -3060,7 +3067,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_caldav"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"async-trait",
|
||||
@@ -3100,7 +3107,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_carddav"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -3132,7 +3139,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_dav"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -3157,7 +3164,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_dav_push"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -3182,7 +3189,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_frontend"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"askama",
|
||||
"askama_web",
|
||||
@@ -3215,7 +3222,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_ical"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"chrono",
|
||||
@@ -3233,7 +3240,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_oidc"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
@@ -3248,7 +3255,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_store"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -3282,7 +3289,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_store_sqlite"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
@@ -3303,7 +3310,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustical_xml"
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"quick-xml",
|
||||
"thiserror 2.0.16",
|
||||
@@ -3349,9 +3356,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.4"
|
||||
version = "0.103.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc"
|
||||
checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
@@ -3425,16 +3432,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
version = "1.0.225"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
@@ -3449,10 +3457,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
name = "serde_core"
|
||||
version = "1.0.225"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.225"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -3461,24 +3478,26 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.143"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_path_to_error"
|
||||
version = "0.1.17"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
|
||||
checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3501,11 +3520,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.0.0"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
|
||||
checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3530,7 +3549,7 @@ dependencies = [
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.11.1",
|
||||
"indexmap 2.11.4",
|
||||
"schemars 0.9.0",
|
||||
"schemars 1.0.4",
|
||||
"serde",
|
||||
@@ -3690,7 +3709,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"hashbrown 0.15.5",
|
||||
"hashlink",
|
||||
"indexmap 2.11.1",
|
||||
"indexmap 2.11.4",
|
||||
"log",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
@@ -4081,9 +4100,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.26.2"
|
||||
version = "0.26.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"
|
||||
checksum = "05f63835928ca123f1bef57abbcd23bb2ba0ac9ae1235f1e65bda0d06e7786bd"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
@@ -4122,19 +4141,19 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_spanned 0.6.9",
|
||||
"toml_datetime 0.6.11",
|
||||
"toml_edit",
|
||||
"toml_edit 0.22.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.9.5"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8"
|
||||
checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0"
|
||||
dependencies = [
|
||||
"indexmap 2.11.1",
|
||||
"serde",
|
||||
"serde_spanned 1.0.0",
|
||||
"toml_datetime 0.7.0",
|
||||
"indexmap 2.11.4",
|
||||
"serde_core",
|
||||
"serde_spanned 1.0.2",
|
||||
"toml_datetime 0.7.2",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow",
|
||||
@@ -4151,11 +4170,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.0"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
|
||||
checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4164,7 +4183,7 @@ version = "0.22.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||
dependencies = [
|
||||
"indexmap 2.11.1",
|
||||
"indexmap 2.11.4",
|
||||
"serde",
|
||||
"serde_spanned 0.6.9",
|
||||
"toml_datetime 0.6.11",
|
||||
@@ -4173,10 +4192,22 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.2"
|
||||
name = "toml_edit"
|
||||
version = "0.23.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10"
|
||||
checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b"
|
||||
dependencies = [
|
||||
"indexmap 2.11.4",
|
||||
"toml_datetime 0.7.2",
|
||||
"toml_parser",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
@@ -4189,9 +4220,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||
|
||||
[[package]]
|
||||
name = "toml_writer"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
|
||||
checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
@@ -4227,7 +4258,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"indexmap 2.11.1",
|
||||
"indexmap 2.11.4",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
"sync_wrapper",
|
||||
@@ -4589,18 +4620,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.14.5+wasi-0.2.4"
|
||||
version = "0.14.7+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4"
|
||||
checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
|
||||
dependencies = [
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.0+wasi-0.2.4"
|
||||
version = "1.0.1+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24"
|
||||
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
@@ -4613,9 +4644,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.101"
|
||||
version = "0.2.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b"
|
||||
checksum = "ab10a69fbd0a177f5f649ad4d8d3305499c42bab9aef2f7ff592d0ec8f833819"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
@@ -4626,9 +4657,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.101"
|
||||
version = "0.2.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb"
|
||||
checksum = "0bb702423545a6007bbc368fde243ba47ca275e549c8a28617f56f6ba53b1d1c"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
@@ -4640,9 +4671,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.51"
|
||||
version = "0.4.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe"
|
||||
checksum = "a0b221ff421256839509adbb55998214a70d829d3a28c69b4a6672e9d2a42f67"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
@@ -4653,9 +4684,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.101"
|
||||
version = "0.2.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d"
|
||||
checksum = "fc65f4f411d91494355917b605e1480033152658d71f722a90647f56a70c88a0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -4663,9 +4694,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.101"
|
||||
version = "0.2.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa"
|
||||
checksum = "ffc003a991398a8ee604a401e194b6b3a39677b3173d6e74495eb51b82e99a32"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -4676,18 +4707,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.101"
|
||||
version = "0.2.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1"
|
||||
checksum = "293c37f4efa430ca14db3721dfbe48d8c33308096bd44d80ebaa775ab71ba1cf"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.78"
|
||||
version = "0.3.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12"
|
||||
checksum = "fbe734895e869dc429d78c4b433f8d17d95f8d05317440b4fad5ab2d33e596dc"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@@ -4733,13 +4764,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.61.2"
|
||||
version = "0.62.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||
checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link 0.1.3",
|
||||
"windows-link 0.2.0",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
@@ -4780,20 +4811,20 @@ checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.4"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
||||
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
"windows-link 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.4.2"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
"windows-link 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5038,9 +5069,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.45.1"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36"
|
||||
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
members = ["crates/*"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.9.5"
|
||||
version = "0.9.8"
|
||||
edition = "2024"
|
||||
description = "A CalDAV server"
|
||||
documentation = "https://lennart-k.github.io/rustical/"
|
||||
|
||||
@@ -68,19 +68,32 @@ pub async fn route_get<C: CalendarStore, S: SubscriptionStore>(
|
||||
for object in &objects {
|
||||
vtimezones.extend(object.get_vtimezones());
|
||||
match object.get_data() {
|
||||
CalendarObjectComponent::Event(EventObject {
|
||||
CalendarObjectComponent::Event(
|
||||
EventObject {
|
||||
event,
|
||||
timezones: object_timezones,
|
||||
..
|
||||
}) => {
|
||||
},
|
||||
overrides,
|
||||
) => {
|
||||
timezones.extend(object_timezones);
|
||||
ical_calendar_builder = ical_calendar_builder.add_event(event.clone());
|
||||
for _override in overrides {
|
||||
ical_calendar_builder =
|
||||
ical_calendar_builder.add_event(_override.event.clone());
|
||||
}
|
||||
CalendarObjectComponent::Todo(TodoObject(todo)) => {
|
||||
}
|
||||
CalendarObjectComponent::Todo(TodoObject(todo), overrides) => {
|
||||
ical_calendar_builder = ical_calendar_builder.add_todo(todo.clone());
|
||||
for _override in overrides {
|
||||
ical_calendar_builder = ical_calendar_builder.add_todo(_override.0.clone());
|
||||
}
|
||||
CalendarObjectComponent::Journal(JournalObject(journal)) => {
|
||||
}
|
||||
CalendarObjectComponent::Journal(JournalObject(journal), overrides) => {
|
||||
ical_calendar_builder = ical_calendar_builder.add_journal(journal.clone());
|
||||
for _override in overrides {
|
||||
ical_calendar_builder = ical_calendar_builder.add_journal(_override.0.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use ical::{
|
||||
generator::Emitter,
|
||||
parser::{Component, ComponentMut},
|
||||
};
|
||||
use rustical_dav::header::Overwrite;
|
||||
use rustical_ical::{CalendarObject, CalendarObjectType};
|
||||
use rustical_store::{
|
||||
Calendar, CalendarMetadata, CalendarStore, SubscriptionStore, auth::Principal,
|
||||
@@ -21,6 +22,7 @@ pub async fn route_import<C: CalendarStore, S: SubscriptionStore>(
|
||||
Path((principal, cal_id)): Path<(String, String)>,
|
||||
user: Principal,
|
||||
State(resource_service): State<CalendarResourceService<C, S>>,
|
||||
overwrite: Overwrite,
|
||||
body: String,
|
||||
) -> Result<Response, Error> {
|
||||
if !user.is_principal(&principal) {
|
||||
@@ -100,7 +102,9 @@ pub async fn route_import<C: CalendarStore, S: SubscriptionStore>(
|
||||
};
|
||||
|
||||
let cal_store = resource_service.cal_store;
|
||||
cal_store.import_calendar(new_cal, objects, false).await?;
|
||||
cal_store
|
||||
.import_calendar(new_cal, objects, overwrite.is_true())
|
||||
.await?;
|
||||
|
||||
Ok(StatusCode::OK.into_response())
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use rustical_ical::CalendarObject;
|
||||
use rustical_store::CalendarStore;
|
||||
use rustical_store::auth::Principal;
|
||||
use std::str::FromStr;
|
||||
use tracing::instrument;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
#[instrument(skip(cal_store))]
|
||||
pub async fn get_event<C: CalendarStore>(
|
||||
@@ -78,9 +78,10 @@ pub async fn put_event<C: CalendarStore>(
|
||||
true
|
||||
};
|
||||
|
||||
let object = match CalendarObject::from_ics(body) {
|
||||
let object = match CalendarObject::from_ics(body.clone()) {
|
||||
Ok(obj) => obj,
|
||||
Err(_) => {
|
||||
debug!("invalid calendar data:\n{body}");
|
||||
return Err(Error::PreconditionFailed(Precondition::ValidCalendarData));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,6 +15,10 @@ pub struct EventObject {
|
||||
}
|
||||
|
||||
impl EventObject {
|
||||
pub fn get_uid(&self) -> &str {
|
||||
self.event.get_uid()
|
||||
}
|
||||
|
||||
pub fn get_dtstart(&self) -> Result<Option<CalDateTime>, Error> {
|
||||
if let Some(dtstart) = self.event.get_dtstart() {
|
||||
Ok(Some(CalDateTime::parse_prop(dtstart, &self.timezones)?))
|
||||
@@ -92,6 +96,7 @@ impl EventObject {
|
||||
&self,
|
||||
start: Option<DateTime<Utc>>,
|
||||
end: Option<DateTime<Utc>>,
|
||||
overrides: &[EventObject],
|
||||
) -> Result<Vec<IcalEvent>, Error> {
|
||||
if let Some(mut rrule_set) = self.recurrence_ruleset()? {
|
||||
if let Some(start) = start {
|
||||
@@ -107,13 +112,30 @@ impl EventObject {
|
||||
.get_dtend()?
|
||||
.map(|dtend| dtend.as_datetime().into_owned() - dtstart.as_datetime().into_owned());
|
||||
|
||||
for date in dates {
|
||||
'recurrence: for date in dates {
|
||||
let date = CalDateTime::from(date);
|
||||
let dateformat = if dtstart.is_date() {
|
||||
date.format_date()
|
||||
} else {
|
||||
date.format()
|
||||
};
|
||||
|
||||
for _override in overrides {
|
||||
if let Some(override_id) = &_override
|
||||
.event
|
||||
.get_recurrence_id()
|
||||
.as_ref()
|
||||
.expect("overrides have a recurrence id")
|
||||
.value
|
||||
&& override_id == &dateformat
|
||||
{
|
||||
// We have an override for this occurence
|
||||
//
|
||||
events.push(_override.event.clone());
|
||||
continue 'recurrence;
|
||||
}
|
||||
}
|
||||
|
||||
let mut ev = self.event.clone().mutable();
|
||||
ev.remove_property("RRULE");
|
||||
ev.remove_property("RDATE");
|
||||
@@ -229,10 +251,18 @@ END:VEVENT\r\n",
|
||||
#[test]
|
||||
fn test_expand_recurrence() {
|
||||
let event = CalendarObject::from_ics(ICS.to_string()).unwrap();
|
||||
let event = event.event().unwrap();
|
||||
let (event, overrides) = if let crate::CalendarObjectComponent::Event(
|
||||
main_event,
|
||||
overrides,
|
||||
) = event.get_data()
|
||||
{
|
||||
(main_event, overrides)
|
||||
} else {
|
||||
panic!()
|
||||
};
|
||||
|
||||
let events: Vec<String> = event
|
||||
.expand_recurrence(None, None)
|
||||
.expand_recurrence(None, None, overrides)
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|event| Emitter::generate(&event))
|
||||
|
||||
@@ -3,3 +3,9 @@ use ical::parser::ical::component::IcalJournal;
|
||||
|
||||
#[derive(Debug, Clone, From)]
|
||||
pub struct JournalObject(pub IcalJournal);
|
||||
|
||||
impl JournalObject {
|
||||
pub fn get_uid(&self) -> &str {
|
||||
self.0.get_uid()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,18 +56,75 @@ impl rustical_xml::ValueDeserialize for CalendarObjectType {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CalendarObjectComponent {
|
||||
Event(EventObject),
|
||||
Todo(TodoObject),
|
||||
Journal(JournalObject),
|
||||
Event(EventObject, Vec<EventObject>),
|
||||
Todo(TodoObject, Vec<TodoObject>),
|
||||
Journal(JournalObject, Vec<JournalObject>),
|
||||
}
|
||||
|
||||
impl Default for CalendarObjectComponent {
|
||||
fn default() -> Self {
|
||||
Self::Event(EventObject::default())
|
||||
impl CalendarObjectComponent {
|
||||
fn from_events(mut events: Vec<EventObject>) -> Result<Self, Error> {
|
||||
let main_event = events
|
||||
.extract_if(.., |event| event.event.get_recurrence_id().is_none())
|
||||
.next()
|
||||
.expect("there must be one main event");
|
||||
let overrides = events;
|
||||
for event in &overrides {
|
||||
if event.get_uid() != main_event.get_uid() {
|
||||
return Err(Error::InvalidData(
|
||||
"Calendar object contains multiple UIDs".to_owned(),
|
||||
));
|
||||
}
|
||||
if event.event.get_recurrence_id().is_none() {
|
||||
return Err(Error::InvalidData(
|
||||
"Calendar object can only contain one main component".to_owned(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(Self::Event(main_event, overrides))
|
||||
}
|
||||
fn from_todos(mut todos: Vec<TodoObject>) -> Result<Self, Error> {
|
||||
let main_todo = todos
|
||||
.extract_if(.., |todo| todo.0.get_recurrence_id().is_none())
|
||||
.next()
|
||||
.expect("there must be one main event");
|
||||
let overrides = todos;
|
||||
for todo in &overrides {
|
||||
if todo.get_uid() != main_todo.get_uid() {
|
||||
return Err(Error::InvalidData(
|
||||
"Calendar object contains multiple UIDs".to_owned(),
|
||||
));
|
||||
}
|
||||
if todo.0.get_recurrence_id().is_none() {
|
||||
return Err(Error::InvalidData(
|
||||
"Calendar object can only contain one main component".to_owned(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(Self::Todo(main_todo, overrides))
|
||||
}
|
||||
fn from_journals(mut journals: Vec<JournalObject>) -> Result<Self, Error> {
|
||||
let main_journal = journals
|
||||
.extract_if(.., |journal| journal.0.get_recurrence_id().is_none())
|
||||
.next()
|
||||
.expect("there must be one main event");
|
||||
let overrides = journals;
|
||||
for journal in &overrides {
|
||||
if journal.get_uid() != main_journal.get_uid() {
|
||||
return Err(Error::InvalidData(
|
||||
"Calendar object contains multiple UIDs".to_owned(),
|
||||
));
|
||||
}
|
||||
if journal.0.get_recurrence_id().is_none() {
|
||||
return Err(Error::InvalidData(
|
||||
"Calendar object can only contain one main component".to_owned(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(Self::Journal(main_journal, overrides))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CalendarObject {
|
||||
data: CalendarObjectComponent,
|
||||
properties: Vec<Property>,
|
||||
@@ -84,16 +141,16 @@ impl CalendarObject {
|
||||
"multiple calendars, only one allowed".to_owned(),
|
||||
));
|
||||
}
|
||||
if cal.events.len()
|
||||
+ cal.alarms.len()
|
||||
+ cal.todos.len()
|
||||
+ cal.journals.len()
|
||||
+ cal.free_busys.len()
|
||||
|
||||
if !cal.events.is_empty() as u8
|
||||
+ !cal.todos.is_empty() as u8
|
||||
+ !cal.journals.is_empty() as u8
|
||||
+ !cal.free_busys.is_empty() as u8
|
||||
!= 1
|
||||
{
|
||||
// https://datatracker.ietf.org/doc/html/rfc4791#section-4.1
|
||||
return Err(Error::InvalidData(
|
||||
"iCalendar object is only allowed to have exactly one component".to_owned(),
|
||||
"iCalendar object must have exactly one component type".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -111,12 +168,27 @@ impl CalendarObject {
|
||||
.map(|timezone| (timezone.get_tzid().to_owned(), timezone))
|
||||
.collect();
|
||||
|
||||
let data = if let Some(event) = cal.events.into_iter().next() {
|
||||
CalendarObjectComponent::Event(EventObject { event, timezones })
|
||||
} else if let Some(todo) = cal.todos.into_iter().next() {
|
||||
CalendarObjectComponent::Todo(todo.into())
|
||||
} else if let Some(journal) = cal.journals.into_iter().next() {
|
||||
CalendarObjectComponent::Journal(journal.into())
|
||||
let data = if !cal.events.is_empty() {
|
||||
CalendarObjectComponent::from_events(
|
||||
cal.events
|
||||
.into_iter()
|
||||
.map(|event| EventObject {
|
||||
event,
|
||||
timezones: timezones.clone(),
|
||||
})
|
||||
.collect(),
|
||||
)?
|
||||
} else if !cal.todos.is_empty() {
|
||||
CalendarObjectComponent::from_todos(
|
||||
cal.todos.into_iter().map(|todo| todo.into()).collect(),
|
||||
)?
|
||||
} else if !cal.journals.is_empty() {
|
||||
CalendarObjectComponent::from_journals(
|
||||
cal.journals
|
||||
.into_iter()
|
||||
.map(|journal| journal.into())
|
||||
.collect(),
|
||||
)?
|
||||
} else {
|
||||
return Err(Error::InvalidData(
|
||||
"iCalendar component type not supported :(".to_owned(),
|
||||
@@ -141,9 +213,11 @@ impl CalendarObject {
|
||||
|
||||
pub fn get_id(&self) -> &str {
|
||||
match &self.data {
|
||||
CalendarObjectComponent::Todo(todo) => todo.0.get_uid(),
|
||||
CalendarObjectComponent::Event(event) => event.event.get_uid(),
|
||||
CalendarObjectComponent::Journal(journal) => journal.0.get_uid(),
|
||||
// We've made sure before that the first component exists and all components share the
|
||||
// same UID
|
||||
CalendarObjectComponent::Todo(todo, _) => todo.0.get_uid(),
|
||||
CalendarObjectComponent::Event(event, _) => event.event.get_uid(),
|
||||
CalendarObjectComponent::Journal(journal, _) => journal.0.get_uid(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,33 +238,40 @@ impl CalendarObject {
|
||||
|
||||
pub fn get_object_type(&self) -> CalendarObjectType {
|
||||
match self.data {
|
||||
CalendarObjectComponent::Todo(_) => CalendarObjectType::Todo,
|
||||
CalendarObjectComponent::Event(_) => CalendarObjectType::Event,
|
||||
CalendarObjectComponent::Journal(_) => CalendarObjectType::Journal,
|
||||
CalendarObjectComponent::Todo(_, _) => CalendarObjectType::Todo,
|
||||
CalendarObjectComponent::Event(_, _) => CalendarObjectType::Event,
|
||||
CalendarObjectComponent::Journal(_, _) => CalendarObjectType::Journal,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_first_occurence(&self) -> Result<Option<CalDateTime>, Error> {
|
||||
match &self.data {
|
||||
CalendarObjectComponent::Event(event) => event.get_dtstart(),
|
||||
CalendarObjectComponent::Event(main_event, overrides) => Ok(overrides
|
||||
.iter()
|
||||
.chain([main_event].into_iter())
|
||||
.map(|event| event.get_dtstart())
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.min()),
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_last_occurence(&self) -> Result<Option<CalDateTime>, Error> {
|
||||
match &self.data {
|
||||
CalendarObjectComponent::Event(event) => event.get_last_occurence(),
|
||||
CalendarObjectComponent::Event(main_event, overrides) => Ok(overrides
|
||||
.iter()
|
||||
.chain([main_event].into_iter())
|
||||
.map(|event| event.get_last_occurence())
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.max()),
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn event(&self) -> Option<&EventObject> {
|
||||
match &self.data {
|
||||
CalendarObjectComponent::Event(event) => Some(event),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expand_recurrence(
|
||||
&self,
|
||||
start: Option<DateTime<Utc>>,
|
||||
@@ -198,10 +279,10 @@ impl CalendarObject {
|
||||
) -> Result<String, Error> {
|
||||
// Only events can be expanded
|
||||
match &self.data {
|
||||
CalendarObjectComponent::Event(event) => {
|
||||
CalendarObjectComponent::Event(main_event, overrides) => {
|
||||
let cal = IcalCalendar {
|
||||
properties: self.properties.clone(),
|
||||
events: event.expand_recurrence(start, end)?,
|
||||
events: main_event.expand_recurrence(start, end, overrides)?,
|
||||
..Default::default()
|
||||
};
|
||||
Ok(cal.generate())
|
||||
|
||||
@@ -3,3 +3,9 @@ use ical::parser::ical::component::IcalTodo;
|
||||
|
||||
#[derive(Debug, Clone, From)]
|
||||
pub struct TodoObject(pub IcalTodo);
|
||||
|
||||
impl TodoObject {
|
||||
pub fn get_uid(&self) -> &str {
|
||||
self.0.get_uid()
|
||||
}
|
||||
}
|
||||
|
||||
30
crates/ical/tests/test_cal_object.rs
Normal file
30
crates/ical/tests/test_cal_object.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use rustical_ical::CalendarObject;
|
||||
|
||||
const MULTI_VEVENT: &str = r#"
|
||||
BEGIN:VCALENDAR
|
||||
PRODID:-//Example Corp.//CalDAV Client//EN
|
||||
VERSION:2.0
|
||||
BEGIN:VEVENT
|
||||
UID:2@example.com
|
||||
SUMMARY:Weekly Meeting
|
||||
DTSTAMP:20041210T183838Z
|
||||
DTSTART:20041206T120000Z
|
||||
DTEND:20041206T130000Z
|
||||
RRULE:FREQ=WEEKLY
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
UID:2@example.com
|
||||
SUMMARY:Weekly Meeting
|
||||
RECURRENCE-ID:20041213T120000Z
|
||||
DTSTAMP:20041210T183838Z
|
||||
DTSTART:20041213T130000Z
|
||||
DTEND:20041213T140000Z
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn parse_calendar_object() {
|
||||
let object = CalendarObject::from_ics(MULTI_VEVENT.to_string()).unwrap();
|
||||
object.expand_recurrence(None, None).unwrap();
|
||||
}
|
||||
Reference in New Issue
Block a user