initial commit.
This commit is contained in:
commit
0bfe9f1ef2
9 changed files with 808 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
/.vscode
|
496
Cargo.lock
generated
Normal file
496
Cargo.lock
generated
Normal file
|
@ -0,0 +1,496 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[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"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ciborium"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
|
||||
dependencies = [
|
||||
"ciborium-io",
|
||||
"ciborium-ll",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ciborium-io"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
|
||||
|
||||
[[package]]
|
||||
name = "ciborium-ll"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
|
||||
dependencies = [
|
||||
"ciborium-io",
|
||||
"half",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.158"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "markdown-ast"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0a3144cdf6273c7c25b0b2821a499ad980ff01f8902f85268d5ba35a0eabf9d"
|
||||
dependencies = [
|
||||
"pulldown-cmark",
|
||||
"pulldown-cmark-to-cmark",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "noteriety"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"ciborium",
|
||||
"markdown-ast",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb4e75767fbc9d92b90e4d0c011f61358cde9513b31ef07ea3631b15ffc3b4fd"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"getopts",
|
||||
"memchr",
|
||||
"pulldown-cmark-escape",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark-escape"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark-to-cmark"
|
||||
version = "15.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9c77db841443d89a57ae94f22d29c022f6d9f41b00bddbf1f4024dbaf4bdce1"
|
||||
dependencies = [
|
||||
"pulldown-cmark",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.208"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.208"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
3
Cargo.toml
Normal file
3
Cargo.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = [ "crates/*" ]
|
8
README.md
Normal file
8
README.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
# noteriety
|
||||
|
||||
very simple outliner and notes app using gtk4.
|
||||
|
||||
|
||||
## license
|
||||
|
||||
this work is licensed under cc by-nc-sa 4.0.
|
12
crates/noteriety/Cargo.toml
Normal file
12
crates/noteriety/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "noteriety"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
chrono = { version = "0.4.38", features = ["serde"] }
|
||||
ciborium = "0.2.2"
|
||||
markdown-ast = "0.1.1"
|
||||
serde = { version = "1.0.205", features = ["derive"] }
|
||||
thiserror = "1.0.63"
|
||||
uuid = { version = "1.10.0", features = ["serde", "v4"] }
|
25
crates/noteriety/src/error.rs
Normal file
25
crates/noteriety/src/error.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
#[error("could not create noteriety data directory")]
|
||||
DataDirCreate,
|
||||
#[error("could not read noteriety data directory")]
|
||||
DataDirRead,
|
||||
#[error("could not write noteriety data directory")]
|
||||
DataDirWrite,
|
||||
#[error("could not create notebook directory")]
|
||||
NotebookDirCreate,
|
||||
#[error("could not load notebook directory")]
|
||||
NotebookDirRead,
|
||||
#[error("could not write notebook directory")]
|
||||
NotebookDirWrite,
|
||||
#[error("could not create note file")]
|
||||
NoteFileCreate,
|
||||
#[error("could not read note file")]
|
||||
NoteFileRead,
|
||||
#[error("could not write note file")]
|
||||
NoteFileWrite,
|
||||
#[error("could not parse data dir from config file")]
|
||||
ConfigDataDirParse,
|
||||
}
|
3
crates/noteriety/src/lib.rs
Normal file
3
crates/noteriety/src/lib.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub mod error;
|
||||
pub mod notebook;
|
||||
pub mod note;
|
147
crates/noteriety/src/note.rs
Normal file
147
crates/noteriety/src/note.rs
Normal file
|
@ -0,0 +1,147 @@
|
|||
use crate::error::Error;
|
||||
use chrono::Utc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{Read, Write},
|
||||
path::Path,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// note is a representation of an individually saved note.
|
||||
/// for ordering comparison purposes, the `created_at` attribute is used.
|
||||
/// for equality comparison purposes, the `id` attribute is used.
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct Note {
|
||||
/// a note id can be dynamic, or statically assigned.
|
||||
/// in the context of noteriety, they are only used
|
||||
/// to differentiate notes with identical titles.
|
||||
pub id: uuid::Uuid,
|
||||
pub title: String,
|
||||
/// todo: replace body type with something more appropriate.
|
||||
/// a rope-backed buffer, perhaps.
|
||||
body: String,
|
||||
created_at: chrono::DateTime<chrono::Utc>,
|
||||
/// if a note has never been updated since its creation, updated_at will be none.
|
||||
updated_at: Option<chrono::DateTime<chrono::Utc>>,
|
||||
}
|
||||
|
||||
impl PartialEq for Note {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Note {}
|
||||
|
||||
impl PartialOrd for Note {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
self.created_at.partial_cmp(&other.created_at)
|
||||
}
|
||||
}
|
||||
|
||||
impl Note {
|
||||
pub fn new<T>(title: T) -> Self
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
Self {
|
||||
id: Uuid::new_v4(),
|
||||
title: title.as_ref().to_string(),
|
||||
body: Default::default(),
|
||||
created_at: chrono::Utc::now(),
|
||||
updated_at: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn title<T>(self, title: T) -> Self
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
Self {
|
||||
id: self.id,
|
||||
title: title.as_ref().to_string(),
|
||||
body: self.body,
|
||||
created_at: self.created_at,
|
||||
updated_at: Some(Utc::now())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn body<T>(self, body: T) -> Self where T: AsRef<str> {
|
||||
Self {
|
||||
id: self.id,
|
||||
title: self.title,
|
||||
body: body.as_ref().to_string(),
|
||||
created_at: self.created_at,
|
||||
updated_at: Some(Utc::now()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write<W>(&self, write_dst: W) -> Result<(), Error>
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
ciborium::into_writer(self, write_dst).map_err(|_| Error::NoteFileWrite)
|
||||
}
|
||||
|
||||
pub fn write_path<P>(&self, path: P) -> Result<(), Error>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let file = File::open(path).map_err(|_| Error::NoteFileRead)?;
|
||||
self.write(file)
|
||||
}
|
||||
|
||||
pub fn read<R>(read_src: R) -> Result<Note, Error>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
ciborium::from_reader(read_src).map_err(|_| Error::NoteFileRead)
|
||||
}
|
||||
|
||||
pub fn read_path<P>(path: P) -> Result<Self, Error>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let file = File::open(path).map_err(|_| Error::NoteFileRead)?;
|
||||
Self::read(file)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::Note;
|
||||
use chrono::DateTime;
|
||||
|
||||
#[test]
|
||||
fn same_titles_are_not_eq() {
|
||||
let note1 = Note::new("a title");
|
||||
let note2 = Note::new("a title");
|
||||
let note3 = Note::new("another title");
|
||||
|
||||
assert!(note1.ne(¬e2));
|
||||
assert!(note1.ne(¬e3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn are_date_ordered() {
|
||||
let note1 = Note {
|
||||
id: Default::default(),
|
||||
title: Default::default(),
|
||||
body: Default::default(),
|
||||
created_at: DateTime::from_timestamp(2000000000, 0).unwrap(),
|
||||
updated_at: Default::default(),
|
||||
};
|
||||
|
||||
let note2 = Note {
|
||||
id: Default::default(),
|
||||
title: Default::default(),
|
||||
body: Default::default(),
|
||||
created_at: DateTime::from_timestamp(1000000000, 0).unwrap(),
|
||||
updated_at: Default::default(),
|
||||
};
|
||||
|
||||
assert!(note1.created_at.gt(¬e2.created_at));
|
||||
assert!(note1.gt(¬e2));
|
||||
}
|
||||
}
|
112
crates/noteriety/src/notebook.rs
Normal file
112
crates/noteriety/src/notebook.rs
Normal file
|
@ -0,0 +1,112 @@
|
|||
use std::{
|
||||
fs::{self, DirEntry},
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use crate::{error::Error, note::Note};
|
||||
|
||||
/// a notebook is a representation of a named collection of notes and child notebooks.
|
||||
/// notebooks are ephemeral, and are represented on-disk by the directory tree.
|
||||
#[derive(Default)]
|
||||
pub struct Notebook {
|
||||
pub root_path: PathBuf,
|
||||
pub name: String,
|
||||
pub child_notes: Vec<Note>,
|
||||
pub child_notebooks: Vec<Notebook>,
|
||||
}
|
||||
|
||||
impl Notebook {
|
||||
/// creates a new note with the provided title and root directory.
|
||||
/// at this time, the presence of the directory tree is not verified.
|
||||
pub fn new(root_path: PathBuf, name: String) -> Self {
|
||||
Self {
|
||||
root_path,
|
||||
name,
|
||||
child_notes: vec![],
|
||||
child_notebooks: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// parses a notebook tree.
|
||||
/// this function is recursive.
|
||||
pub fn read<P>(root_path: P) -> Result<Self, Error>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
let direntries: Vec<DirEntry> = fs::read_dir(&root_path)
|
||||
.map_err(|_| Error::NotebookDirRead)?
|
||||
.filter_map(Result::ok)
|
||||
.collect();
|
||||
|
||||
let child_notebooks: Vec<Notebook> = direntries
|
||||
.iter()
|
||||
.filter(|de| de.metadata().is_ok_and(|de| de.is_file()))
|
||||
.filter_map(|de| Result::ok(Notebook::read(de.path())))
|
||||
.collect();
|
||||
|
||||
let child_notes: Vec<Note> = direntries
|
||||
.iter()
|
||||
.filter(|de| de.metadata().is_ok_and(|de| de.is_file()))
|
||||
.filter_map(|de| Result::ok(Note::read_path(de.path().to_string_lossy().into_owned())))
|
||||
.collect();
|
||||
|
||||
let name = root_path
|
||||
.as_ref()
|
||||
.file_stem()
|
||||
.map(|s| s.to_string_lossy().to_string())
|
||||
.unwrap_or(String::from_str("unknown").unwrap());
|
||||
|
||||
Ok(Self {
|
||||
root_path: root_path.as_ref().to_path_buf(),
|
||||
child_notebooks,
|
||||
child_notes,
|
||||
name,
|
||||
})
|
||||
}
|
||||
|
||||
/// overwrites the contents of this notebook with the contents of the struct.
|
||||
/// this function is recursive.
|
||||
pub fn write(&self) -> Result<(), Error> {
|
||||
fs::create_dir(&self.root_path).map_err(|_| Error::NotebookDirCreate)?;
|
||||
|
||||
for notebook in &self.child_notebooks {
|
||||
notebook.write()?;
|
||||
}
|
||||
|
||||
for note in &self.child_notes {
|
||||
let path = PathBuf::new().join(¬e.title);
|
||||
note.write_path(path)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// creates, but does not write, a notebook within this notebook.
|
||||
pub fn create_notebook<N>(mut self, notebook_name: N) -> Result<(), Error>
|
||||
where
|
||||
N: AsRef<str>,
|
||||
{
|
||||
self.child_notebooks.push(Self {
|
||||
root_path: self.root_path.join(notebook_name.as_ref()),
|
||||
name: notebook_name.as_ref().to_string(),
|
||||
child_notes: vec![],
|
||||
child_notebooks: vec![],
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// creates, but does not write, a new note within this notebook.
|
||||
pub fn create_note<N>(mut self, title: N, body: String) -> Result<(), Error>
|
||||
where
|
||||
N: AsRef<str>,
|
||||
{
|
||||
self.child_notes.push(Note::new(title).body(body));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// writes a note to this notebook's root path.
|
||||
pub fn write_note(&self, note: &Note) -> Result<(), Error> {
|
||||
note.write_path(self.root_path.join(¬e.title))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue