Initial commit uwu
This commit is contained in:
commit
03ef223108
|
@ -0,0 +1 @@
|
|||
/target
|
|
@ -0,0 +1,887 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[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.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"time",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.0.0-rc.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7843ae7a539bef687e018bf9edf7e87728024b29d02b0f8409726be8880ae1a"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"indexmap",
|
||||
"lazy_static",
|
||||
"os_str_bytes",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.0.0-rc.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cae3cc2f259ea636871f5da15b0ac033f1821d7a5506c3d1bfbdde201f14c803"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "confy"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2913470204e9e8498a0f31f17f90a0de801ae92c8c5ac18c49af4819e6786697"
|
||||
dependencies = [
|
||||
"directories",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
|
||||
dependencies = [
|
||||
"encode_unicode",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"terminal_size",
|
||||
"unicode-width",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dialoguer"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61579ada4ec0c6031cfac3f86fdba0d195a7ebeb5e36693bd53cb5999a25beeb"
|
||||
dependencies = [
|
||||
"console",
|
||||
"lazy_static",
|
||||
"tempfile",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "directories"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "exitcode"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.112"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paris"
|
||||
version = "1.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a25b44bc50356452ab4fdcdd6d6b0f70eddc4f9fd16c9ba142f69e74fb195165"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
||||
|
||||
[[package]]
|
||||
name = "sled"
|
||||
version = "0.34.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
"fs2",
|
||||
"fxhash",
|
||||
"libc",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"rand",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "terminal_size"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinymark"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
"clap",
|
||||
"confy",
|
||||
"dialoguer",
|
||||
"exitcode",
|
||||
"paris",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sled",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619"
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.9.1+zstd.1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "538b8347df9257b7fbce37677ef7535c00a3c7bf1f81023cc328ed7fe4b41de8"
|
||||
dependencies = [
|
||||
"zstd-safe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-safe"
|
||||
version = "4.1.2+zstd.1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb4cfe2f6e6d35c5d27ecd9d256c4b6f7933c4895654917460ec56c29336cc1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"zstd-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-sys"
|
||||
version = "1.6.2+zstd.1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2daf2f248d9ea44454bfcb2516534e8b8ad2fc91bf818a1885495fc42bc8ac9f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
|
@ -0,0 +1,35 @@
|
|||
[package]
|
||||
name = "tinymark"
|
||||
description = "A tiny bookmark manager"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
authors = ["Erin Nova <contact@the-system.eu.org>"]
|
||||
license = "CNPLv7+"
|
||||
readme = "README.md"
|
||||
homepage = "https://git.lavender.software/erin/tinymark"
|
||||
repository = "https://git.lavender.software/erin/tinymark"
|
||||
keywords = ["cli", "bookmark", "tiny"]
|
||||
categories = ["command-line-utilities"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z" # Optimize for size.
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
||||
|
||||
[dependencies]
|
||||
url = { version = "2.2.2", features = ["serde"] }
|
||||
uuid = { version = "0.8.2", features = ["v5", "serde"] }
|
||||
sled = { version = "0.34.7", features = ["compression"] }
|
||||
bincode = "1.3.3"
|
||||
paris = { version = "1.5", features = ["macros"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
clap = { version = "3.0.0-rc.9", features = ["derive"] }
|
||||
exitcode = "1.1.2"
|
||||
serde_json = "1.0"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
dialoguer = "0.9.0"
|
||||
confy = "0.4"
|
||||
serde_derive = "1.0.132"
|
|
@ -0,0 +1,36 @@
|
|||
# TinyMark
|
||||
A tiny bookmark manager.
|
||||
|
||||
## About
|
||||
This is just a small tool I've made for myself to organize my bookmarks in a simple way,
|
||||
without needing a browser.
|
||||
|
||||
It doesn't support icons or much of anything else right now.
|
||||
|
||||
A configuration file will be stored in `~/.config/tinymark/tinymark.toml`
|
||||
By default the database will be stored in `~/.local/share/tinymark`
|
||||
|
||||
## Using
|
||||
List stored bookmarks:
|
||||
`tinymark list`
|
||||
|
||||
Add a bookmark:
|
||||
`tinymark add https://example.com name`
|
||||
|
||||
With optional tags & description:
|
||||
`tinymark add https://example.com name "test description" tags,separated,by,comma`
|
||||
|
||||
Delete a previously added bookmark:
|
||||
`tinymark delete <link>`
|
||||
|
||||
You can export all the stored bookmarks to a JSON file with `tinymark export <file>`
|
||||
|
||||
You can then import a previously exported JSON file with `tinymark import <file>`
|
||||
|
||||
## JSON
|
||||
This program can output in JSON format if you supply it with the `--json` argument.
|
||||
|
||||
Any command that returns a Bookmark will return a JSON serialized object of it.
|
||||
|
||||
Otherwise it will return a 'status' key of value 'success' or 'fail',
|
||||
along with a 'reason' value with a full-length output.
|
|
@ -0,0 +1,171 @@
|
|||
use url::Url;
|
||||
use std::env::VarError;
|
||||
use chrono::Utc;
|
||||
use crate::structures::Bookmark;
|
||||
use paris::*;
|
||||
use crate::database;
|
||||
use serde_json::json;
|
||||
use std::path::PathBuf;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
use dialoguer::{
|
||||
Select,
|
||||
theme::ColorfulTheme,
|
||||
console::Term
|
||||
};
|
||||
|
||||
pub fn edit(json: bool, url: &Option<Url>, path: Option<PathBuf>) {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": "unsupported command",
|
||||
}));
|
||||
std::process::exit(exitcode::DATAERR);
|
||||
} else {
|
||||
match url {
|
||||
Some(link) => {
|
||||
println!("User selected item :\n{}", link);
|
||||
},
|
||||
None => {
|
||||
match database::get_all(json, path) {
|
||||
Some(bookmarks) => {
|
||||
let mut items: Vec<&Url> = Vec::new();
|
||||
for i in &bookmarks {
|
||||
items.push(&i.link);
|
||||
}
|
||||
let selection = Select::with_theme(&ColorfulTheme::default())
|
||||
.items(&items)
|
||||
.default(0)
|
||||
.interact_on_opt(&Term::stderr()).unwrap();
|
||||
|
||||
match selection {
|
||||
Some(index) => println!("User selected item :\n{}", bookmarks[index]),
|
||||
None => println!("User did not select anything")
|
||||
}
|
||||
},
|
||||
None => {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": "an error ocurred in running your command",
|
||||
}));
|
||||
} else {
|
||||
warn!("an error ocurred in running your command");
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(url: &Url, name: &String, description: &Option<String>, tags: &Vec<String>, json: bool, path: Option<PathBuf>) {
|
||||
let bookmark = Bookmark {
|
||||
link: url.to_owned(),
|
||||
label: name.to_string(),
|
||||
description: description.to_owned(),
|
||||
tags: tags.to_vec(),
|
||||
container: None,
|
||||
created_at: Utc::now(),
|
||||
};
|
||||
|
||||
database::insert_entry(&bookmark, json, path);
|
||||
if json {
|
||||
println!("{}", serde_json::to_string(&bookmark).unwrap());
|
||||
} else {
|
||||
println!("Added new bookmark!");
|
||||
println!("{}", bookmark);
|
||||
};
|
||||
}
|
||||
|
||||
pub fn list(json: bool, path: Option<PathBuf>) {
|
||||
match database::get_all(json, path) {
|
||||
Some(bookmarks) => {
|
||||
for i in bookmarks {
|
||||
if json {
|
||||
println!("{}", serde_json::to_string(&i).unwrap());
|
||||
} else {
|
||||
println!("{}", i);
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": "an error ocurred in running your command",
|
||||
}));
|
||||
} else {
|
||||
warn!("an error ocurred in running your command");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn env_err(json: bool, e: VarError) {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": e.to_string(),
|
||||
}));
|
||||
} else {
|
||||
warn!("couldn't read $HOME environment variable: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn export(file_path: PathBuf, json: bool, path: Option<PathBuf>) {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": "unsupported command",
|
||||
}));
|
||||
} else {
|
||||
let file = match File::create(&file_path) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
warn!("error opening file! {}", e);
|
||||
std::process::exit(exitcode::DATAERR);
|
||||
},
|
||||
};
|
||||
let writer = BufWriter::new(file);
|
||||
|
||||
match database::get_all(json, path) {
|
||||
Some(bookmarks) => serde_json::to_writer(writer, &bookmarks).unwrap(),
|
||||
None => std::process::exit(exitcode::IOERR),
|
||||
}
|
||||
info!("Succesfully exported bookmarks to {}!", file_path.to_str().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn import(file_path: PathBuf, json: bool) {
|
||||
match json {
|
||||
true => {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": "unsupported command",
|
||||
}));
|
||||
},
|
||||
false => {
|
||||
let file = match File::open(&file_path) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
warn!("error opening file! {}", e);
|
||||
std::process::exit(exitcode::DATAERR);
|
||||
}
|
||||
};
|
||||
let reader = BufReader::new(file);
|
||||
|
||||
let bookmarks: Vec<Bookmark> = match serde_json::from_reader(reader) {
|
||||
Ok(contents) => contents,
|
||||
Err(e) => {
|
||||
warn!("error serializing file! {}", e);
|
||||
std::process::exit(exitcode::DATAERR);
|
||||
}
|
||||
};
|
||||
|
||||
info!("succesfully imported bookmarks from {}!", file_path.to_str().unwrap());
|
||||
|
||||
},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
use crate::structures::Bookmark;
|
||||
use crate::commands::env_err;
|
||||
|
||||
use paris::*;
|
||||
use url::Url;
|
||||
use std::env;
|
||||
use serde_json::json;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn open_database(json: bool, path: Option<PathBuf>) -> Option<sled::Db> {
|
||||
let db: sled::Db;
|
||||
let database_path = match path {
|
||||
Some(path) => path,
|
||||
None => {
|
||||
let key = "HOME";
|
||||
match env::var(key) {
|
||||
Ok(val) => {
|
||||
let mut tmp_path = PathBuf::new();
|
||||
tmp_path.push(val);
|
||||
tmp_path.push(".local/share/tinymark");
|
||||
tmp_path
|
||||
},
|
||||
Err(e) => {
|
||||
env_err(json, e);
|
||||
std::process::exit(exitcode::DATAERR);
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
match sled::open(database_path) {
|
||||
Ok(database) => db = database,
|
||||
Err(error) => {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": error.to_string(),
|
||||
}));
|
||||
} else {
|
||||
error!("error in opening database: {}", error);
|
||||
}
|
||||
return None;
|
||||
},
|
||||
};
|
||||
|
||||
return Some(db);
|
||||
}
|
||||
|
||||
pub fn insert_entry(entry: &Bookmark, json: bool, path: Option<PathBuf>) {
|
||||
let db = match open_database(json, path) {
|
||||
Some(database) => database,
|
||||
None => std::process::exit(exitcode::NOINPUT),
|
||||
};
|
||||
|
||||
let bytes;
|
||||
match bincode::serialize(&entry) {
|
||||
Ok(result) => bytes = result,
|
||||
Err(error) => {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": error.to_string(),
|
||||
}));
|
||||
} else {
|
||||
error!("failed serializing entry: {}", error);
|
||||
}
|
||||
std::process::exit(exitcode::DATAERR);
|
||||
},
|
||||
};
|
||||
|
||||
match db.insert(entry.link.to_string(), bytes) {
|
||||
Ok(_) => {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "success",
|
||||
"reason": "inserted entry",
|
||||
}));
|
||||
} else {
|
||||
info!("succesfully inserted entry <i>{}", entry.link);
|
||||
}
|
||||
},
|
||||
Err(error) => {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": error.to_string(),
|
||||
}));
|
||||
} else {
|
||||
error!("failed to insert entry <i>{}</i>!\n {}", entry.link, error);
|
||||
}
|
||||
std::process::exit(exitcode::IOERR);
|
||||
},
|
||||
}
|
||||
|
||||
db.flush().unwrap();
|
||||
}
|
||||
|
||||
pub fn remove_entry(link: &Url, json: bool, path: Option<PathBuf>) {
|
||||
let db = match open_database(json, path) {
|
||||
Some(database) => database,
|
||||
None => std::process::exit(exitcode::NOINPUT),
|
||||
};
|
||||
|
||||
match db.remove(link.to_string()) {
|
||||
Ok(_) => info!("succesfully removed entry <i>{}", link),
|
||||
Err(error) => {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": error.to_string(),
|
||||
}));
|
||||
} else {
|
||||
error!("failed to remove entry <i>{}</i>!\n {}", link, error);
|
||||
}
|
||||
std::process::exit(exitcode::IOERR);
|
||||
},
|
||||
}
|
||||
|
||||
db.flush().unwrap();
|
||||
}
|
||||
|
||||
pub fn get_all(json: bool, path: Option<PathBuf>) -> Option<Vec<Bookmark>> {
|
||||
let db = match open_database(json, path) {
|
||||
Some(database) => database,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let first_key = match db.first() {
|
||||
Ok(pair) => {
|
||||
pair.unwrap().0
|
||||
},
|
||||
Err(error) => {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": error.to_string(),
|
||||
}));
|
||||
} else {
|
||||
error!("failed to get first key: {}", error);
|
||||
}
|
||||
return None;
|
||||
},
|
||||
};
|
||||
|
||||
let mut bookmarks_vector: Vec<Bookmark> = Vec::new();
|
||||
let mut iter = db.range(first_key..);
|
||||
|
||||
loop {
|
||||
match iter.next() {
|
||||
Some(x) => {
|
||||
let read_entry;
|
||||
match bincode::deserialize(&x.unwrap().1) {
|
||||
Ok(result) => read_entry = result,
|
||||
Err(error) => {
|
||||
if json {
|
||||
println!("{}", json!({
|
||||
"status": "fail",
|
||||
"reason": error.to_string(),
|
||||
}));
|
||||
} else {
|
||||
error!("failed deserializing entry: {}", error);
|
||||
}
|
||||
return None;
|
||||
},
|
||||
}
|
||||
bookmarks_vector.push(read_entry);
|
||||
},
|
||||
None => { break },
|
||||
}
|
||||
}
|
||||
|
||||
return Some(bookmarks_vector);
|
||||
}
|
||||
|
||||
/* not working for some reason
|
||||
pub fn update_entry(entry: &Bookmark) {
|
||||
let db = open_database();
|
||||
|
||||
let bytes = match bincode::serialize(&entry) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(error) => panic!("failed to serialize entry: {}", error),
|
||||
};
|
||||
|
||||
let old_entry: Bookmark = get_entry(&entry.id.to_simple().to_string()).unwrap();
|
||||
|
||||
let old_bytes = match bincode::serialize(&old_entry) {
|
||||
Ok(bytes) => bytes,
|
||||
Err(error) => panic!("failed to serialize entry: {}", error),
|
||||
};
|
||||
|
||||
match db.compare_and_swap(
|
||||
entry.id.to_simple().to_string(),
|
||||
Some(&old_bytes),
|
||||
Some(&bytes)) {
|
||||
Ok(_) => info!("succesfully swapped entry <i>{}", entry.id),
|
||||
Err(error) => warn!("failed to swap entry <i>{}</i>!\n {}", entry.id, error),
|
||||
}
|
||||
|
||||
db.flush();
|
||||
}
|
||||
|
||||
pub fn get_entry(id: &str) -> Option<Bookmark> {
|
||||
let db = open_database();
|
||||
|
||||
let db_entry = match db.get(id) {
|
||||
Ok(entry) => entry,
|
||||
Err(error) => panic!("failed to get old entry: {}", error),
|
||||
};
|
||||
|
||||
if let Some(entry) = db_entry {
|
||||
let read_entry = match bincode::deserialize(&entry) {
|
||||
Ok(entry) => entry,
|
||||
Err(error) => panic!("failed to deserialize entry: {}", error),
|
||||
};
|
||||
return Some(read_entry);
|
||||
} else {
|
||||
warn!("failed to find entry");
|
||||
return None;
|
||||
};
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,61 @@
|
|||
pub mod structures;
|
||||
mod tests;
|
||||
mod database;
|
||||
mod commands;
|
||||
|
||||
use crate::structures::{Commands, Cli, Config};
|
||||
use clap::Parser;
|
||||
use paris::*;
|
||||
use std::path::PathBuf;
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let cfg: Config = confy::load("tinymark").unwrap();
|
||||
confy::store("tinymark", &cfg).unwrap();
|
||||
/*
|
||||
println!("The configuration is:");
|
||||
println!("{:#?}", cfg);*/
|
||||
|
||||
if cfg.tui {
|
||||
warn!("TUI is not implemented yet!");
|
||||
std::process::exit(exitcode::DATAERR);
|
||||
}
|
||||
|
||||
|
||||
let args = Cli::parse();
|
||||
let json: bool;
|
||||
|
||||
if cfg.json {
|
||||
json = true;
|
||||
} else {
|
||||
json = args.json;
|
||||
}
|
||||
|
||||
let storage_path: Option<PathBuf> = match &cfg.storage_location {
|
||||
Some(path) => {
|
||||
let HOME = env::var("HOME");
|
||||
match HOME {
|
||||
Ok(val) => {
|
||||
let mut new_path = PathBuf::new();
|
||||
new_path.push(val);
|
||||
new_path.push(path);
|
||||
Some(new_path)
|
||||
},
|
||||
Err(e) => {
|
||||
commands::env_err(json, e);
|
||||
None
|
||||
},
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
match &args.command {
|
||||
Commands::Add { url, name, description, tags } => commands::add(url, name, description, tags, json, storage_path),
|
||||
Commands::Edit { url } => commands::edit(json, url, storage_path),
|
||||
Commands::Delete { url } => database::remove_entry(url, json, storage_path),
|
||||
Commands::List { } => commands::list(json, storage_path),
|
||||
Commands::Export { file } => commands::export(file.to_path_buf(), json, storage_path),
|
||||
Commands::Import { file } => commands::import(file.to_path_buf(), json),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
use clap::{AppSettings, Parser, Subcommand};
|
||||
use std::fmt;
|
||||
use chrono::prelude::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
pub tui: bool,
|
||||
pub json: bool,
|
||||
pub storage_location: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Config {
|
||||
tui: false,
|
||||
json: false,
|
||||
storage_location: Some(PathBuf::from(r"$HOME/.local/share/tinymark")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Bookmark {
|
||||
//pub id: Uuid,
|
||||
pub link: Url,
|
||||
pub label: String,
|
||||
pub description: Option<String>,
|
||||
pub tags: Vec<String>,
|
||||
pub container: Option<Uuid>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
fn do_nothing() {
|
||||
//yea
|
||||
}
|
||||
|
||||
impl fmt::Display for Bookmark {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
println!("Bookmark: {}", &self.label);
|
||||
println!("{}", &self.link);
|
||||
|
||||
match &self.description {
|
||||
Some(s) => println!("{}", s),
|
||||
None => do_nothing(),
|
||||
};
|
||||
|
||||
print!("[");
|
||||
for i in &self.tags {
|
||||
print!("{},", i);
|
||||
}
|
||||
print!("]");
|
||||
|
||||
write!(f, "\nCreated at: {}\n", &self.created_at.with_timezone(&Local).to_rfc2822())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Container {
|
||||
pub id: Uuid,
|
||||
pub label: String,
|
||||
pub container: Option<Uuid>,
|
||||
pub container_type: ContainerTypes,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum ContainerTypes {
|
||||
Folder,
|
||||
Group,
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct Cli {
|
||||
/// Output as JSON
|
||||
#[clap(long)]
|
||||
pub json: bool,
|
||||
|
||||
#[clap(subcommand)]
|
||||
pub command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Commands {
|
||||
/// Add a bookmark
|
||||
#[clap(setting(AppSettings::ArgRequiredElseHelp))]
|
||||
Add {
|
||||
/// The URL to add
|
||||
url: Url,
|
||||
|
||||
/// The name of the bookmark
|
||||
name: String,
|
||||
|
||||
/// A short description
|
||||
description: Option<String>,
|
||||
|
||||
/// Optional comma-seperated tags
|
||||
tags: Vec<String>
|
||||
},
|
||||
|
||||
/// Edit a bookmark
|
||||
Edit {
|
||||
url: Option<Url>,
|
||||
},
|
||||
|
||||
/// Delete a bookmark
|
||||
#[clap(setting(AppSettings::ArgRequiredElseHelp))]
|
||||
Delete {
|
||||
// The bookmark to delete
|
||||
url: Url,
|
||||
},
|
||||
|
||||
/// List all bookmarks
|
||||
List,
|
||||
|
||||
/// Export the bookmarks to a JSON file
|
||||
#[clap(setting(AppSettings::ArgRequiredElseHelp))]
|
||||
Export {
|
||||
/// The output file
|
||||
file: PathBuf,
|
||||
},
|
||||
|
||||
/// Import bookmarks from a JSON file
|
||||
#[clap(setting(AppSettings::ArgRequiredElseHelp))]
|
||||
Import {
|
||||
/// The input file
|
||||
file: PathBuf,
|
||||
},
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(2 + 2, 4);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue