aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock536
-rw-r--r--Cargo.toml4
-rw-r--r--README.md4
-rw-r--r--flake.lock12
-rw-r--r--flake.nix14
-rw-r--r--src/cli/mod.rs35
-rw-r--r--src/db/categories.rs4
-rw-r--r--src/db/event-color.rs7
-rw-r--r--src/db/event_color.rs14
-rw-r--r--src/db/event_colors.rs12
-rw-r--r--src/db/events.rs64
-rw-r--r--src/db/migrations/01-init.sql (renamed from src/db/migrations/1-init.sql)0
-rw-r--r--src/db/migrations/02-categories.sql (renamed from src/db/migrations/2-categories.sql)0
-rw-r--r--src/db/migrations/03-event-color.sql (renamed from src/db/migrations/3-event-color.sql)0
-rw-r--r--src/db/migrations/04-strict-tables.sql57
-rw-r--r--src/db/mod.rs24
-rw-r--r--src/gui/app.rs9
-rw-r--r--src/gui/form/mod.rs8
-rw-r--r--src/gui/form/repetition.rs2
-rw-r--r--src/main.rs20
-rw-r--r--src/model/event.rs10
-rw-r--r--src/validation/mod.rs4
22 files changed, 525 insertions, 315 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 05d3ceb..4f21afb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,12 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-version = 3
+version = 4
[[package]]
name = "ahash"
-version = "0.8.11"
+version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
+checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [
"cfg-if",
"once_cell",
@@ -15,12 +15,6 @@ dependencies = [
]
[[package]]
-name = "android-tzdata"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
-
-[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -31,9 +25,9 @@ dependencies = [
[[package]]
name = "anstream"
-version = "0.6.18"
+version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
+checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -46,49 +40,50 @@ dependencies = [
[[package]]
name = "anstyle"
-version = "1.0.10"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
[[package]]
name = "anstyle-parse"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
+checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.1.2"
+version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
+checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.6"
+version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
+checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
- "windows-sys 0.59.0",
+ "once_cell_polyfill",
+ "windows-sys 0.61.2",
]
[[package]]
name = "anyhow"
-version = "1.0.93"
+version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
+checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "async-channel"
-version = "2.3.1"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
+checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
dependencies = [
"concurrent-queue",
"event-listener-strategy",
@@ -98,27 +93,27 @@ dependencies = [
[[package]]
name = "autocfg"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bitflags"
-version = "2.6.0"
+version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
[[package]]
name = "bumpalo"
-version = "3.16.0"
+version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
[[package]]
name = "cairo-rs"
-version = "0.20.5"
+version = "0.20.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7fa699e1d7ae691001a811dda5ef0e3e42e1d4119b26426352989df9e94e3e6"
+checksum = "91e3bd0f4e25afa9cabc157908d14eeef9067d6448c49414d17b3fb55f0eadd0"
dependencies = [
"bitflags",
"cairo-sys-rs",
@@ -128,9 +123,9 @@ dependencies = [
[[package]]
name = "cairo-sys-rs"
-version = "0.20.0"
+version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "428290f914b9b86089f60f5d8a9f6e440508e1bcff23b25afd51502b0a2da88f"
+checksum = "059cc746549898cbfd9a47754288e5a958756650ef4652bbb6c5f71a6bda4f8b"
dependencies = [
"glib-sys",
"libc",
@@ -156,18 +151,19 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.1"
+version = "1.2.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
+checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c"
dependencies = [
+ "find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-expr"
-version = "0.17.1"
+version = "0.20.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c360837f8f19e2e4468275138f1c0dec1647d1e17bb7c0215fe3cd7530e93c25"
+checksum = "21be0e1ce6cdb2ee7fff840f922fb04ead349e5cfb1e750b769132d44ce04720"
dependencies = [
"smallvec",
"target-lexicon",
@@ -175,30 +171,29 @@ dependencies = [
[[package]]
name = "cfg-if"
-version = "1.0.0"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "chrono"
-version = "0.4.38"
+version = "0.4.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
+checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
dependencies = [
- "android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
- "windows-targets",
+ "windows-link",
]
[[package]]
name = "clap"
-version = "4.5.21"
+version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
+checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
dependencies = [
"clap_builder",
"clap_derive",
@@ -206,9 +201,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.21"
+version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
+checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
dependencies = [
"anstream",
"anstyle",
@@ -218,9 +213,9 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.5.18"
+version = "4.5.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
+checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
dependencies = [
"heck",
"proc-macro2",
@@ -230,15 +225,15 @@ dependencies = [
[[package]]
name = "clap_lex"
-version = "0.7.3"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
+checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
[[package]]
name = "colorchoice"
-version = "1.0.3"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
+checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "concurrent-queue"
@@ -257,21 +252,21 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "crossbeam-utils"
-version = "0.8.20"
+version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "equivalent"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "event-listener"
-version = "5.3.1"
+version = "5.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
+checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
dependencies = [
"concurrent-queue",
"parking",
@@ -280,9 +275,9 @@ dependencies = [
[[package]]
name = "event-listener-strategy"
-version = "0.5.2"
+version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1"
+checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
dependencies = [
"event-listener",
"pin-project-lite",
@@ -311,6 +306,12 @@ dependencies = [
]
[[package]]
+name = "find-msvc-tools"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
+
+[[package]]
name = "futures-channel"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -375,9 +376,9 @@ dependencies = [
[[package]]
name = "gdk-pixbuf"
-version = "0.20.4"
+version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4c29071a9e92337d8270a85cb0510cda4ac478be26d09ad027cc1d081911b19"
+checksum = "2fd242894c084f4beed508a56952750bce3e96e85eb68fdc153637daa163e10c"
dependencies = [
"gdk-pixbuf-sys",
"gio",
@@ -387,9 +388,9 @@ dependencies = [
[[package]]
name = "gdk-pixbuf-sys"
-version = "0.20.4"
+version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "687343b059b91df5f3fbd87b4307038fa9e647fcc0461d0d3f93e94fee20bf3d"
+checksum = "5b34f3b580c988bd217e9543a2de59823fafae369d1a055555e5f95a8b130b96"
dependencies = [
"gio-sys",
"glib-sys",
@@ -400,9 +401,9 @@ dependencies = [
[[package]]
name = "gdk4"
-version = "0.9.4"
+version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75933c4a86e8a2428814d367e22c733304fdfabc87f415750fd2f55409b6ee48"
+checksum = "4850c9d9c1aecd1a3eb14fadc1cdb0ac0a2298037e116264c7473e1740a32d60"
dependencies = [
"cairo-rs",
"gdk-pixbuf",
@@ -415,9 +416,9 @@ dependencies = [
[[package]]
name = "gdk4-sys"
-version = "0.9.4"
+version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20af0656d543aed3e57ac4120ef76d091c3c42ab1e0507a8febde7cd005640e2"
+checksum = "6f6eb95798e2b46f279cf59005daf297d5b69555428f185650d71974a910473a"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@@ -432,20 +433,21 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.15"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
- "wasi",
+ "r-efi",
+ "wasip2",
]
[[package]]
name = "gio"
-version = "0.20.6"
+version = "0.20.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8826d2a9ad56ce3de1f04bea0bea0daff6f5f1c913cc834996cfea1f9401361c"
+checksum = "8e27e276e7b6b8d50f6376ee7769a71133e80d093bdc363bd0af71664228b831"
dependencies = [
"futures-channel",
"futures-core",
@@ -460,22 +462,22 @@ dependencies = [
[[package]]
name = "gio-sys"
-version = "0.20.6"
+version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b965df6f3534c84816b5c1a7d9efcb5671ae790822de5abe8e299797039529bc"
+checksum = "521e93a7e56fc89e84aea9a52cfc9436816a4b363b030260b699950ff1336c83"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
name = "glib"
-version = "0.20.6"
+version = "0.20.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86bd3e4ee7998ab5a135d900db56930cc19ad16681adf245daff54f618b9d5e1"
+checksum = "ffc4b6e352d4716d84d7dde562dd9aee2a7d48beb872dd9ece7f2d1515b2d683"
dependencies = [
"bitflags",
"futures-channel",
@@ -494,9 +496,9 @@ dependencies = [
[[package]]
name = "glib-macros"
-version = "0.20.5"
+version = "0.20.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7d21ca27acfc3e91da70456edde144b4ac7c36f78ee77b10189b3eb4901c156"
+checksum = "e8084af62f09475a3f529b1629c10c429d7600ee1398ae12dd3bf175d74e7145"
dependencies = [
"heck",
"proc-macro-crate",
@@ -507,9 +509,9 @@ dependencies = [
[[package]]
name = "glib-sys"
-version = "0.20.6"
+version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d0b1827e8621fc42c0dfb228e5d57ff6a71f9699e666ece8113f979ad87c2de"
+checksum = "8ab79e1ed126803a8fb827e3de0e2ff95191912b8db65cee467edb56fc4cc215"
dependencies = [
"libc",
"system-deps",
@@ -517,9 +519,9 @@ dependencies = [
[[package]]
name = "gobject-sys"
-version = "0.20.4"
+version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4c674d2ff8478cf0ec29d2be730ed779fef54415a2fb4b565c52def62696462"
+checksum = "ec9aca94bb73989e3cfdbf8f2e0f1f6da04db4d291c431f444838925c4c63eda"
dependencies = [
"glib-sys",
"libc",
@@ -528,9 +530,9 @@ dependencies = [
[[package]]
name = "graphene-rs"
-version = "0.20.4"
+version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f53144c7fe78292705ff23935f1477d511366fb2f73c43d63b37be89076d2fe"
+checksum = "6b86dfad7d14251c9acaf1de63bc8754b7e3b4e5b16777b6f5a748208fe9519b"
dependencies = [
"glib",
"graphene-sys",
@@ -539,9 +541,9 @@ dependencies = [
[[package]]
name = "graphene-sys"
-version = "0.20.4"
+version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e741797dc5081e59877a4d72c442c72d61efdd99161a0b1c1b29b6b988934b99"
+checksum = "df583a85ba2d5e15e1797e40d666057b28bc2f60a67c9c24145e6db2cc3861ea"
dependencies = [
"glib-sys",
"libc",
@@ -551,9 +553,9 @@ dependencies = [
[[package]]
name = "gsk4"
-version = "0.9.4"
+version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b36933c1e79df378aa6e606576e680358a9582ed8c16f33e94899636e6fa6df6"
+checksum = "61f5e72f931c8c9f65fbfc89fe0ddc7746f147f822f127a53a9854666ac1f855"
dependencies = [
"cairo-rs",
"gdk4",
@@ -566,9 +568,9 @@ dependencies = [
[[package]]
name = "gsk4-sys"
-version = "0.9.4"
+version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0877a9d485bd9ba5262b0c9bce39e63750e525e3aebeb359d271ca1f0e111f1d"
+checksum = "755059de55fa6f85a46bde8caf03e2184c96bfda1f6206163c72fb0ea12436dc"
dependencies = [
"cairo-sys-rs",
"gdk4-sys",
@@ -582,9 +584,9 @@ dependencies = [
[[package]]
name = "gtk4"
-version = "0.9.4"
+version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9376d14d7e33486c54823a42bef296e882b9f25cb4c52b52f4d1d57bbadb5b6d"
+checksum = "f274dd0102c21c47bbfa8ebcb92d0464fab794a22fad6c3f3d5f165139a326d6"
dependencies = [
"cairo-rs",
"field-offset",
@@ -603,9 +605,9 @@ dependencies = [
[[package]]
name = "gtk4-macros"
-version = "0.9.3"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7c518d5dd41c57385c7cd30af52e261820c897fc1144e558bb88c303d048ae2"
+checksum = "0ed1786c4703dd196baf7e103525ce0cf579b3a63a0570fe653b7ee6bac33999"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@@ -615,9 +617,9 @@ dependencies = [
[[package]]
name = "gtk4-sys"
-version = "0.9.4"
+version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e653b0a9001ba9be1ffddb9373bfe9a111f688222f5aeee2841481300d91b55a"
+checksum = "41e03b01e54d77c310e1d98647d73f996d04b2f29b9121fe493ea525a7ec03d6"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
@@ -643,9 +645,9 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.15.1"
+version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
+checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
[[package]]
name = "hashlink"
@@ -664,14 +666,15 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "iana-time-zone"
-version = "0.1.61"
+version = "0.1.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
+checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
+ "log",
"wasm-bindgen",
"windows-core",
]
@@ -687,40 +690,41 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "2.6.0"
+version = "2.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
+checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
dependencies = [
"equivalent",
- "hashbrown 0.15.1",
+ "hashbrown 0.16.1",
]
[[package]]
name = "is_terminal_polyfill"
-version = "1.70.1"
+version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itoa"
-version = "1.0.11"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "js-sys"
-version = "0.3.72"
+version = "0.3.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
+checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
dependencies = [
+ "once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
-version = "0.2.164"
+version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
+checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]]
name = "libsqlite3-sys"
@@ -734,15 +738,15 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.22"
+version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "memchr"
-version = "2.7.4"
+version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
[[package]]
name = "memoffset"
@@ -764,15 +768,21 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.20.2"
+version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "once_cell_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "pango"
-version = "0.20.6"
+version = "0.20.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71e34e7ca2c52e3933d7e5251409a82b83725fa9d6d48fbdaacec056b3a0554a"
+checksum = "6576b311f6df659397043a5fa8a021da8f72e34af180b44f7d57348de691ab5c"
dependencies = [
"gio",
"glib",
@@ -782,9 +792,9 @@ dependencies = [
[[package]]
name = "pango-sys"
-version = "0.20.4"
+version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84fd65917bf12f06544ae2bbc200abf9fc0a513a5a88a0fa81013893aef2b838"
+checksum = "186909673fc09be354555c302c0b3dcf753cd9fa08dcb8077fa663c80fb243fa"
dependencies = [
"glib-sys",
"gobject-sys",
@@ -800,9 +810,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "pin-project-lite"
-version = "0.2.15"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pin-utils"
@@ -812,38 +822,44 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
+checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "proc-macro-crate"
-version = "3.2.0"
+version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
+checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro2"
-version = "1.0.89"
+version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
+checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.37"
+version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
dependencies = [
"proc-macro2",
]
[[package]]
+name = "r-efi"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
+[[package]]
name = "rusqlite"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -878,31 +894,47 @@ dependencies = [
]
[[package]]
+name = "rustversion"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+
+[[package]]
name = "ryu"
-version = "1.0.18"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "semver"
-version = "1.0.23"
+version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
+checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]]
name = "serde"
-version = "1.0.215"
+version = "1.0.228"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.215"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
@@ -911,23 +943,24 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.133"
+version = "1.0.145"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
+checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
+ "serde_core",
]
[[package]]
name = "serde_spanned"
-version = "0.6.8"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
+checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776"
dependencies = [
- "serde",
+ "serde_core",
]
[[package]]
@@ -938,18 +971,15 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "slab"
-version = "0.4.9"
+version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
-dependencies = [
- "autocfg",
-]
+checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
[[package]]
name = "smallvec"
-version = "1.13.2"
+version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "strsim"
@@ -959,9 +989,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
-version = "2.0.87"
+version = "2.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
+checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
dependencies = [
"proc-macro2",
"quote",
@@ -970,9 +1000,9 @@ dependencies = [
[[package]]
name = "system-deps"
-version = "7.0.3"
+version = "7.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66d23aaf9f331227789a99e8de4c91bf46703add012bdfd45fdecdfb2975a005"
+checksum = "48c8f33736f986f16d69b6cb8b03f55ddcad5c41acc4ccc39dd88e84aa805e7f"
dependencies = [
"cfg-expr",
"heck",
@@ -983,24 +1013,24 @@ dependencies = [
[[package]]
name = "target-lexicon"
-version = "0.12.16"
+version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
+checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c"
[[package]]
name = "thiserror"
-version = "2.0.3"
+version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"
+checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "2.0.3"
+version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"
+checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
dependencies = [
"proc-macro2",
"quote",
@@ -1009,43 +1039,60 @@ dependencies = [
[[package]]
name = "toml"
-version = "0.8.19"
+version = "0.9.10+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
+checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48"
dependencies = [
- "serde",
+ "indexmap",
+ "serde_core",
"serde_spanned",
"toml_datetime",
- "toml_edit",
+ "toml_parser",
+ "toml_writer",
+ "winnow",
]
[[package]]
name = "toml_datetime"
-version = "0.6.8"
+version = "0.7.5+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
+checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
dependencies = [
- "serde",
+ "serde_core",
]
[[package]]
name = "toml_edit"
-version = "0.22.22"
+version = "0.23.10+spec-1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
+checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269"
dependencies = [
"indexmap",
- "serde",
- "serde_spanned",
"toml_datetime",
+ "toml_parser",
+ "winnow",
+]
+
+[[package]]
+name = "toml_parser"
+version = "1.0.6+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
+dependencies = [
"winnow",
]
[[package]]
+name = "toml_writer"
+version = "1.0.6+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607"
+
+[[package]]
name = "unicode-ident"
-version = "1.0.13"
+version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
+checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "utf8parse"
@@ -1055,11 +1102,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
-version = "1.11.0"
+version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
+checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
dependencies = [
"getrandom",
+ "js-sys",
+ "wasm-bindgen",
]
[[package]]
@@ -1070,9 +1119,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version-compare"
-version = "0.2.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
+checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e"
[[package]]
name = "version_check"
@@ -1081,31 +1130,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
-name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
+name = "wasip2"
+version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
+dependencies = [
+ "wit-bindgen",
+]
[[package]]
name = "wasm-bindgen"
-version = "0.2.95"
+version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
+checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
dependencies = [
"cfg-if",
"once_cell",
+ "rustversion",
"wasm-bindgen-macro",
+ "wasm-bindgen-shared",
]
[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.95"
+name = "wasm-bindgen-macro"
+version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
+checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
dependencies = [
"bumpalo",
- "log",
- "once_cell",
"proc-macro2",
"quote",
"syn",
@@ -1113,50 +1175,71 @@ dependencies = [
]
[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.95"
+name = "wasm-bindgen-shared"
+version = "0.2.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.62.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
+dependencies = [
+ "windows-implement",
+ "windows-interface",
+ "windows-link",
+ "windows-result",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
+checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
+ "proc-macro2",
"quote",
- "wasm-bindgen-macro-support",
+ "syn",
]
[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.95"
+name = "windows-interface"
+version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
+checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn",
- "wasm-bindgen-backend",
- "wasm-bindgen-shared",
]
[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.95"
+name = "windows-link"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
-name = "windows-core"
-version = "0.52.0"
+name = "windows-result"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [
- "windows-targets",
+ "windows-link",
]
[[package]]
-name = "windows-sys"
-version = "0.52.0"
+name = "windows-strings"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
dependencies = [
- "windows-targets",
+ "windows-link",
]
[[package]]
@@ -1169,6 +1252,15 @@ dependencies = [
]
[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1234,27 +1326,33 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
-version = "0.6.20"
+version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
+checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
dependencies = [
"memchr",
]
[[package]]
+name = "wit-bindgen"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
+
+[[package]]
name = "zerocopy"
-version = "0.7.35"
+version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.7.35"
+version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
dependencies = [
"proc-macro2",
"quote",
diff --git a/Cargo.toml b/Cargo.toml
index 356fdcf..783a374 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0"
-async-channel = "2.3"
+async-channel = "2.5"
chrono = { version = "0.4", features = [ "serde" ] }
clap = { version = "4.5", features = ["derive"] }
gtk4 = { version = "0.9", features = [ "v4_4" ] }
@@ -14,4 +14,4 @@ rusqlite_migration = "1.3"
serde = { version = "1.0", features = [ "derive" ] }
serde_json = "1.0"
thiserror = "2.0"
-uuid = { version = "1.11", features = [ "v4" ] }
+uuid = { version = "1.19", features = [ "v4" ] }
diff --git a/README.md b/README.md
index 43eccf4..8f54d46 100644
--- a/README.md
+++ b/README.md
@@ -30,10 +30,10 @@ Run tests with:
cargo test
```
-Get today’s events with:
+Show options:
```bash
-cargo run -- --list-today
+cargo run -- --help
```
# TODO
diff --git a/flake.lock b/flake.lock
index c1c5849..3a3e378 100644
--- a/flake.lock
+++ b/flake.lock
@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1731830981,
- "narHash": "sha256-EQ7ManBtAfkY9/G7Kv3gvn0eHvlhDrR5zZQigs0InaY=",
+ "lastModified": 1766237803,
+ "narHash": "sha256-5/WndtUGc78FAO3Bq3YJmeurT4tNszDUnHkOBgsJOjA=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "a1ccef7b2d4da7baaeba4e8e2647f39a349d8203",
+ "rev": "d32ebe0ae29af4ebf51115153a2515dc1d35bdb7",
"type": "github"
},
"original": {
@@ -47,11 +47,11 @@
]
},
"locked": {
- "lastModified": 1731820690,
- "narHash": "sha256-/hHFMTD+FGURXZ4JtfXoIgpy87zL505pVi6AL76Wc+U=",
+ "lastModified": 1766198367,
+ "narHash": "sha256-f1L1rCEu2Zew6zdiZ38jJDZd65ktE7UN+Gqn2LHPiFI=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "bbab2ab9e1932133b1996baa1dc00fefe924ca81",
+ "rev": "66bb33fdfb50b1ee724381c3f5d6012dac6c89b3",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index facf906..4331952 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,8 +2,10 @@
inputs = {
nixpkgs.url = "github:nixos/nixpkgs";
flake-utils.url = "github:numtide/flake-utils";
- rust-overlay.url = "github:oxalica/rust-overlay";
- rust-overlay.inputs.nixpkgs.follows = "nixpkgs";
+ rust-overlay = {
+ url = "github:oxalica/rust-overlay";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
};
outputs = { self, nixpkgs, rust-overlay, flake-utils, ... }:
@@ -18,12 +20,14 @@
{
devShell = mkShell {
buildInputs = [
- rust-bin.stable."1.82.0".default
- rust-analyzer
+ cargo-edit
+ cargo-update
cargo-watch
- pkg-config
graphene
gtk4
+ pkg-config
+ rust-analyzer
+ rust-bin.stable."1.92.0".default
sqlite
];
};
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index 3674a08..8069a10 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -1,14 +1,25 @@
use anyhow::Result;
-use chrono::{Local, NaiveDate, NaiveDateTime, TimeZone};
+use chrono::{Local, NaiveDate, NaiveDateTime, TimeDelta, TimeZone};
use rusqlite::Connection;
+use std::ops::{Add, Sub};
use crate::model::event::Event;
+use crate::model::category::Category;
use crate::{db, model::event};
-pub fn today(conn: &Connection) -> Result<String> {
- let today = Local::now().date_naive();
- let events = between_inclusive(conn, today, today)?;
- Ok(format_events(events))
+pub fn parse_date(s: String) -> Option<NaiveDate> {
+ match s.as_str() {
+ "yesterday" => Some(Local::now().sub(TimeDelta::days(1)).date_naive()),
+ "today" => Some(Local::now().date_naive()),
+ "tomorrow" => Some(Local::now().add(TimeDelta::days(1)).date_naive()),
+ _ => NaiveDate::parse_from_str(&s, "%Y-%m-%d").ok(),
+ }
+}
+
+pub fn started_at_date(conn: &Connection, date: NaiveDate) -> Result<String> {
+ let events = between_inclusive(conn, date, date)?;
+ let categories = db::categories::list(conn)?;
+ Ok(format_events(events, categories))
}
pub fn parse_timestamp_range(s: String) -> Option<(NaiveDateTime, NaiveDateTime)> {
@@ -41,7 +52,8 @@ pub fn start_between(conn: &Connection, from: NaiveDateTime, to: NaiveDateTime)
})
.cloned()
.collect::<Vec<Event>>();
- Ok(format_events(events))
+ let categories = db::categories::list(conn)?;
+ Ok(format_events(events, categories))
}
fn between_inclusive(conn: &Connection, from: NaiveDate, to: NaiveDate) -> Result<Vec<Event>> {
@@ -60,12 +72,19 @@ fn between_inclusive(conn: &Connection, from: NaiveDate, to: NaiveDate) -> Resul
Ok(events)
}
-fn format_events(events: Vec<Event>) -> String {
+fn format_events(events: Vec<Event>, categories: Vec<Category>) -> String {
let mut events = events;
events.sort_by_key(|e| e.local_timestamp());
events
.iter()
- .map(|e| format!("{}\n", e.pprint()))
+ .map(|e| {
+ let category = e.category.and_then(|c| categories.clone().into_iter().find(|c2| c == c2.id));
+ let category_str = match category {
+ Some(c) => format!("[{}] ", c.name),
+ None => "".to_string()
+ };
+ return format!("{}{}\n", category_str, e.pprint())
+ })
.collect::<Vec<String>>()
.join("")
}
diff --git a/src/db/categories.rs b/src/db/categories.rs
index ebefb6d..f81b855 100644
--- a/src/db/categories.rs
+++ b/src/db/categories.rs
@@ -5,7 +5,8 @@ use uuid::Uuid;
use crate::model::category::Category;
pub fn list(conn: &Connection) -> Result<Vec<Category>> {
- let mut stmt = conn.prepare("SELECT id, name, color FROM categories")?;
+ let query = r#"SELECT id, name, color FROM categories"#;
+ let mut stmt = conn.prepare(query)?;
let iter = stmt.query_map([], |row| {
Ok(read_category(row.get(0)?, row.get(1)?, row.get(2)?))
@@ -20,6 +21,5 @@ pub fn list(conn: &Connection) -> Result<Vec<Category>> {
fn read_category(id: String, name: String, color: String) -> Result<Category> {
let id = Uuid::parse_str(&id)?;
-
Ok(Category { id, name, color })
}
diff --git a/src/db/event-color.rs b/src/db/event-color.rs
deleted file mode 100644
index 18612e4..0000000
--- a/src/db/event-color.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-pub fn get_default_color(conn: &Connection) -> Result<String> {
-}
-
-// pub fn set_default_color(conon: &Connection, color: &str) -> Result<()> {
-// }
diff --git a/src/db/event_color.rs b/src/db/event_color.rs
deleted file mode 100644
index 33d350b..0000000
--- a/src/db/event_color.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use anyhow::Result;
-use rusqlite::Connection;
-
-pub fn get_default_color(conn: &Connection) -> Result<String> {
- let mut stmt = conn.prepare("SELECT * FROM event_color LIMIT 1")?;
-
- let iter = stmt.query_map([], |row| row.get(0))?;
-
- let mut res = vec![];
- for color in iter {
- res.push(color?)
- }
- Ok(res.first().unwrap_or(&"blue".to_string()).clone())
-}
diff --git a/src/db/event_colors.rs b/src/db/event_colors.rs
new file mode 100644
index 0000000..bf7f541
--- /dev/null
+++ b/src/db/event_colors.rs
@@ -0,0 +1,12 @@
+use anyhow::Result;
+use rusqlite::Connection;
+
+pub fn get_default_color(conn: &Connection) -> Result<String> {
+ let mut stmt = conn.prepare("SELECT * FROM event_colors LIMIT 1")?;
+ let mut iter = stmt.query_map([], |row| row.get(0))?;
+
+ match iter.next() {
+ Some(Ok(color)) => Ok(color),
+ _ => Ok("blue".to_string()),
+ }
+}
diff --git a/src/db/events.rs b/src/db/events.rs
index 1721967..7f09466 100644
--- a/src/db/events.rs
+++ b/src/db/events.rs
@@ -1,11 +1,16 @@
use anyhow::Result;
use chrono::{NaiveDate, NaiveTime};
-use rusqlite::{params, Connection};
+use rusqlite::{named_params, Connection};
use uuid::Uuid;
use crate::model::event::Event;
pub fn insert(conn: &Connection, event: &Event) -> Result<()> {
+ let query = r#"
+ INSERT INTO events (id, date, start, end, name, repetition, category, created, updated)
+ VALUES (:id, :date, :start, :end, :name, :repetition, :category, datetime(), datetime())
+ "#;
+
let repetition = match &event.repetition {
Some(r) => Some(serde_json::to_string(&r)?),
None => None,
@@ -14,14 +19,35 @@ pub fn insert(conn: &Connection, event: &Event) -> Result<()> {
let category = event.category.map(|id| id.hyphenated().to_string());
conn.execute(
- "INSERT INTO events (id, date, start, end, name, repetition, category, created, updated) VALUES (?, ?, ?, ?, ?, ?, ?, datetime(), datetime())",
- params![event.id.hyphenated().to_string(), event.date, event.start, event.end, event.name, repetition, category]
+ query,
+ named_params![
+ ":id": event.id.hyphenated().to_string(),
+ ":date": event.date,
+ ":start": event.start,
+ ":end": event.end,
+ ":name": event.name,
+ ":repetition": repetition,
+ ":category": category
+ ],
)?;
Ok(())
}
pub fn update(conn: &Connection, event: &Event) -> Result<()> {
+ let query = r#"
+ UPDATE events
+ SET
+ date = :date,
+ start = :start,
+ end = :end,
+ name = :name,
+ repetition = :repetition,
+ category = :category,
+ updated = datetime()
+ WHERE id = :id
+ "#;
+
let repetition = match &event.repetition {
Some(r) => Some(serde_json::to_string(&r)?),
None => None,
@@ -30,29 +56,35 @@ pub fn update(conn: &Connection, event: &Event) -> Result<()> {
let category = event.category.map(|id| id.hyphenated().to_string());
conn.execute(
- "UPDATE events SET date = ?, start = ?, end = ?, name = ?, repetition = ?, category = ?, updated = datetime() WHERE id = ?",
- params![event.date, event.start, event.end, event.name, repetition, category, event.id.hyphenated().to_string()]
+ query,
+ named_params![
+ ":date": event.date,
+ ":start": event.start,
+ ":end": event.end,
+ ":name": event.name,
+ ":repetition": repetition,
+ ":category": category,
+ ":id": event.id.hyphenated().to_string()
+ ],
)?;
Ok(())
}
pub fn delete(conn: &Connection, id: &Uuid) -> Result<()> {
- conn.execute(
- "DELETE FROM events WHERE id = ?",
- params![id.hyphenated().to_string()],
- )?;
-
+ let query = r#"DELETE FROM events WHERE id = :id"#;
+ conn.execute(query, named_params![":id": id.hyphenated().to_string()])?;
Ok(())
}
pub fn list_recurring(conn: &Connection) -> Result<Vec<Event>> {
- let mut stmt = conn.prepare(
- "
+ let query = r#"
SELECT id, date, start, end, name, repetition, category
FROM events
- WHERE repetition IS NOT NULL",
- )?;
+ WHERE repetition IS NOT NULL
+ "#;
+
+ let mut stmt = conn.prepare(query)?;
let iter = stmt.query_map([], |row| {
Ok(read_event(
@@ -82,8 +114,8 @@ pub fn list_non_recurring_between(
"
SELECT id, date, start, end, name, category
FROM events
- WHERE
- repetition IS NULL
+ WHERE
+ repetition IS NULL
AND date >= ?
AND date <= ?
",
diff --git a/src/db/migrations/1-init.sql b/src/db/migrations/01-init.sql
index 467e481..467e481 100644
--- a/src/db/migrations/1-init.sql
+++ b/src/db/migrations/01-init.sql
diff --git a/src/db/migrations/2-categories.sql b/src/db/migrations/02-categories.sql
index 0b373d0..0b373d0 100644
--- a/src/db/migrations/2-categories.sql
+++ b/src/db/migrations/02-categories.sql
diff --git a/src/db/migrations/3-event-color.sql b/src/db/migrations/03-event-color.sql
index ec589ea..ec589ea 100644
--- a/src/db/migrations/3-event-color.sql
+++ b/src/db/migrations/03-event-color.sql
diff --git a/src/db/migrations/04-strict-tables.sql b/src/db/migrations/04-strict-tables.sql
new file mode 100644
index 0000000..7a10b31
--- /dev/null
+++ b/src/db/migrations/04-strict-tables.sql
@@ -0,0 +1,57 @@
+-- Categories
+
+ALTER TABLE "categories" RENAME TO "categories_non_strict";
+
+CREATE TABLE IF NOT EXISTS "categories" (
+ "id" TEXT PRIMARY KEY, /* UUID */
+ "name" TEXT NOT NULL UNIQUE,
+ "color" TEXT NOT NULL, /* COLOR */
+ "created" TEXT NOT NULL, /* DATETIME */
+ "updated" TEXT NOT NULL /* DATETIME */
+) STRICT;
+
+INSERT INTO categories (id, name, color, created, updated)
+ SELECT id, name, color, created, updated
+ FROM categories_non_strict;
+
+DROP TABLE categories_non_strict;
+
+-- Event color
+
+CREATE TABLE IF NOT EXISTS "event_colors" (
+ "color" TEXT NOT NULL /* COLOR */
+) STRICT;
+
+INSERT INTO event_colors (color)
+ SELECT color
+ FROM event_color;
+
+DROP TABLE event_color;
+
+-- Events
+
+ALTER TABLE "events" RENAME TO "events_non_strict";
+
+CREATE TABLE IF NOT EXISTS "events" (
+ "id" TEXT PRIMARY KEY, /* UUID */
+ "date" TEXT NOT NULL, /* DATE */
+ "start" TEXT NULL, /* TIME */
+ "end" TEXT NULL, /* TIME */
+ "name" TEXT NOT NULL,
+ "repetition" TEXT NULL, /* JSON */
+ "created" TEXT NOT NULL, /* DATETIME */
+ "updated" TEXT NOT NULL, /* DATETIME */
+ "category" TEXT REFERENCES "categories" ("id")
+) STRICT;
+
+INSERT INTO events (id, date, start, end, name, repetition, created, updated, category)
+ SELECT id, date, start, end, name, repetition, created, updated, category
+ FROM events_non_strict;
+
+DROP TABLE events_non_strict;
+
+DROP INDEX IF EXISTS events_date_index;
+CREATE INDEX events_date_index on events (date);
+
+DROP INDEX IF EXISTS events_repetition_index;
+CREATE INDEX events_repetition_index on events (repetition);
diff --git a/src/db/mod.rs b/src/db/mod.rs
index 20e7f81..0e73f30 100644
--- a/src/db/mod.rs
+++ b/src/db/mod.rs
@@ -1,5 +1,5 @@
pub mod categories;
-pub mod event_color;
+pub mod event_colors;
pub mod events;
use anyhow::Result;
@@ -8,11 +8,23 @@ use rusqlite_migration::{Migrations, M};
pub fn init(db_path: &str) -> Result<Connection> {
let mut conn = Connection::open(db_path)?;
+ apply_migrations(&mut conn)?;
+ set_pragma(&conn, "foreign_keys", "ON")?;
+ set_pragma(&conn, "journal_mode", "wal")?;
+ Ok(conn)
+}
+
+fn apply_migrations(conn: &mut Connection) -> Result<()> {
let migrations = Migrations::new(vec![
- M::up(include_str!("migrations/1-init.sql")),
- M::up(include_str!("migrations/2-categories.sql")),
- M::up(include_str!("migrations/3-event-color.sql")),
+ M::up(include_str!("migrations/01-init.sql")),
+ M::up(include_str!("migrations/02-categories.sql")),
+ M::up(include_str!("migrations/03-event-color.sql")),
+ M::up(include_str!("migrations/04-strict-tables.sql")),
]);
- migrations.to_latest(&mut conn)?;
- Ok(conn)
+ migrations.to_latest(conn)?;
+ Ok(())
+}
+
+fn set_pragma(conn: &Connection, key: &str, value: &str) -> Result<()> {
+ Ok(conn.pragma_update(None, key, value)?)
}
diff --git a/src/gui/app.rs b/src/gui/app.rs
index 5469e53..826f051 100644
--- a/src/gui/app.rs
+++ b/src/gui/app.rs
@@ -2,7 +2,7 @@ use gtk4 as gtk;
use anyhow::Result;
use async_channel::Sender;
-use chrono::{Datelike, Duration, NaiveDate, Weekday};
+use chrono::{Datelike, Duration, NaiveDate};
use rusqlite::Connection;
use std::rc::Rc;
@@ -30,16 +30,13 @@ pub struct App {
impl App {
pub fn new(conn: Rc<Connection>, app: &gtk::Application, tx: Sender<Msg>) -> Result<Self> {
let today = chrono::offset::Local::now().naive_local().date();
- // TODO: error handling
- let start_date =
- NaiveDate::from_isoywd_opt(today.year(), today.iso_week().week(), Weekday::Mon)
- .unwrap();
+ let start_date = today - Duration::days(today.weekday().num_days_from_monday().into());
let end_date = start_date + Duration::days(7 * 4 - 1);
let events = db::events::list_non_recurring_between(&conn, start_date, end_date)?;
let recurring_events = db::events::list_recurring(&conn)?;
let categories = db::categories::list(&conn)?;
- let default_color = db::event_color::get_default_color(&conn)?;
+ let default_color = db::event_colors::get_default_color(&conn)?;
let calendar = calendar::create(
tx.clone(),
diff --git a/src/gui/form/mod.rs b/src/gui/form/mod.rs
index 197bc14..a14fb82 100644
--- a/src/gui/form/mod.rs
+++ b/src/gui/form/mod.rs
@@ -256,10 +256,10 @@ pub async fn show(app: &App, target: Target) {
match event::validate(
id,
- date.buffer().text().to_string(),
- name.buffer().text().to_string(),
- start.buffer().text().to_string(),
- end.buffer().text().to_string(),
+ &date.buffer().text(),
+ &name.buffer().text(),
+ &start.buffer().text(),
+ &end.buffer().text(),
repetition,
category,
) {
diff --git a/src/gui/form/repetition.rs b/src/gui/form/repetition.rs
index 4ed9803..6e7a13f 100644
--- a/src/gui/form/repetition.rs
+++ b/src/gui/form/repetition.rs
@@ -195,7 +195,7 @@ pub fn validate(
// Check until
let until = (if frequency.is_some() {
- match validation::non_empty(model.until.buffer().text().to_string()) {
+ match validation::non_empty(&model.until.buffer().text()) {
Some(until) => match NaiveDate::parse_from_str(&until, event::DATE_FORMAT) {
Ok(until) => Ok(Some(until)),
Err(_) => Err(format!("Can’t parse date from {}", until)),
diff --git a/src/main.rs b/src/main.rs
index 8eafd77..e61a771 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -14,11 +14,11 @@ struct Opt {
#[clap(long = "database", default_value = "database.sqlite3")]
db_path: String,
- /// List today’s events as plain text
- #[clap(long = "list-today")]
- list_today: bool,
+ /// Started at events as plain text
+ #[clap(long = "date")]
+ date: Option<String>,
- /// Start between <timestamp..timestamp> events as plain text
+ /// Started between <timestamp..timestamp> events as plain text
#[clap(long = "start-between")]
start_between: Option<String>,
}
@@ -26,17 +26,17 @@ struct Opt {
fn main() -> Result<()> {
let Opt {
db_path,
- list_today,
+ date,
start_between,
} = Opt::parse();
let conn = db::init(&db_path)?;
- if list_today {
- print!("{}", cli::today(&conn)?);
- } else {
- match start_between.and_then(cli::parse_timestamp_range) {
+
+ match date.and_then(cli::parse_date) {
+ Some(date) => print!("{}", cli::started_at_date(&conn, date)?),
+ None => match start_between.and_then(cli::parse_timestamp_range) {
Some((from, to)) => print!("{}", cli::start_between(&conn, from, to)?),
None => gui::run(conn),
- }
+ },
};
Ok(())
}
diff --git a/src/model/event.rs b/src/model/event.rs
index 98ce416..62e5b12 100644
--- a/src/model/event.rs
+++ b/src/model/event.rs
@@ -65,10 +65,10 @@ pub fn repetitions_between(
pub fn validate(
id: Uuid,
- date: String,
- name: String,
- start: String,
- end: String,
+ date: &str,
+ name: &str,
+ start: &str,
+ end: &str,
repetition: Option<Repetition>,
category: Option<Uuid>,
) -> Option<Event> {
@@ -82,7 +82,7 @@ pub fn validate(
Some(Event {
id,
- date: NaiveDate::parse_from_str(&date, DATE_FORMAT).ok()?,
+ date: NaiveDate::parse_from_str(date, DATE_FORMAT).ok()?,
name: validation::non_empty(name)?,
start,
end,
diff --git a/src/validation/mod.rs b/src/validation/mod.rs
index 07a7c4c..029726d 100644
--- a/src/validation/mod.rs
+++ b/src/validation/mod.rs
@@ -2,7 +2,7 @@ use chrono::NaiveTime;
use crate::model::time;
-pub fn time(time: String) -> Option<Option<NaiveTime>> {
+pub fn time(time: &str) -> Option<Option<NaiveTime>> {
let time = time.trim();
if time.is_empty() {
Some(None)
@@ -11,7 +11,7 @@ pub fn time(time: String) -> Option<Option<NaiveTime>> {
}
}
-pub fn non_empty(str: String) -> Option<String> {
+pub fn non_empty(str: &str) -> Option<String> {
let str = str.trim();
if str.is_empty() {
None