its all unwrap? always has been

This commit is contained in:
EvilMuffinHa 2022-06-12 20:17:24 -04:00
commit 0ff97907bc
12 changed files with 1585 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

794
Cargo.lock generated Normal file
View File

@ -0,0 +1,794 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
dependencies = [
"memchr 0.1.11",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi 0.3.9",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "blake2b_simd"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[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 = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b63edc3f163b3c71ec8aa23f9bd6070f77edbf3d1d198b164afa90ff00e4ec62"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"indexmap",
"lazy_static",
"os_str_bytes",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_derive"
version = "3.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a1132dc3944b31c20dd8b906b3a9f0a5d0243e092d59171414969657ac6aa85"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "crossbeam-utils"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]]
name = "directories"
version = "4.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
dependencies = [
"libc",
"redox_users 0.3.5",
"winapi 0.3.9",
]
[[package]]
name = "dirs-sys"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
dependencies = [
"libc",
"redox_users 0.4.0",
"winapi 0.3.9",
]
[[package]]
name = "enquote"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06c36cb11dbde389f4096111698d8b567c0720e3452fd5ac3e6b4e47e1939932"
dependencies = [
"thiserror",
]
[[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 = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
dependencies = [
"cfg-if",
"libc",
"wasi 0.10.2+wasi-snapshot-preview1",
]
[[package]]
name = "git2"
version = "0.13.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29229cc1b24c0e6062f6e742aa3e256492a5323365e5ed3413599f8a5eff7d6"
dependencies = [
"bitflags",
"libc",
"libgit2-sys",
"log",
"openssl-probe",
"openssl-sys",
"url",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[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.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "jobserver"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
dependencies = [
"libc",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[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.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
[[package]]
name = "libgit2-sys"
version = "0.12.26+1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e1c899248e606fbfe68dcb31d8b0176ebab833b103824af31bddf4b7457494"
dependencies = [
"cc",
"libc",
"libssh2-sys",
"libz-sys",
"openssl-sys",
"pkg-config",
]
[[package]]
name = "libssh2-sys"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca"
dependencies = [
"cc",
"libc",
"libz-sys",
"openssl-sys",
"pkg-config",
"vcpkg",
]
[[package]]
name = "libz-sys"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "matches"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "memchr"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
dependencies = [
"libc",
]
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
dependencies = [
"autocfg",
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "os_str_bytes"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
dependencies = [
"memchr 2.4.1",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pkg-config"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
[[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.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[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.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
"getrandom 0.1.16",
"redox_syscall 0.1.57",
"rust-argon2",
]
[[package]]
name = "redox_users"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom 0.2.4",
"redox_syscall 0.2.10",
]
[[package]]
name = "regex"
version = "0.1.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
dependencies = [
"aho-corasick",
"memchr 0.1.11",
"regex-syntax",
"thread_local",
"utf8-ranges",
]
[[package]]
name = "regex-syntax"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
[[package]]
name = "rust-argon2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]]
name = "rust-ini"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac66e816614e124a692b6ac1b8437237a518c9155a3aacab83a373982630c715"
[[package]]
name = "rustache"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c86de9443c1a5618e0d51bbd8eb6227ead9916446eb8952575a70d1ef7e00209"
dependencies = [
"regex",
"rustc-serialize",
]
[[package]]
name = "rustc-serialize"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
[[package]]
name = "serde"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
[[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.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
[[package]]
name = "themectl"
version = "0.1.0"
dependencies = [
"ansi_term",
"clap",
"directories",
"git2",
"rustache",
"toml",
"url",
"wallpaper",
"yaml-rust",
]
[[package]]
name = "thiserror"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread-id"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
dependencies = [
"kernel32-sys",
"libc",
]
[[package]]
name = "thread_local"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
dependencies = [
"thread-id",
]
[[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-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",
]
[[package]]
name = "utf8-ranges"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wallpaper"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0547c84bf49b1096b20ce49736b86cd27f8225fc426665d3fba19e71e44c4d46"
dependencies = [
"dirs",
"enquote",
"rust-ini",
"winapi 0.3.9",
"winreg",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
[[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-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
[[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 0.3.9",
]
[[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 = "winreg"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16cdb3898397cf7f624c294948669beafaeebc5577d5ec53d0afb76633593597"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]

17
Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "themectl"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "3.0.14", features = ['derive']}
wallpaper = { version = "3.2" }
rustache = { version = "^0.1" }
toml = { version = "0.5" }
yaml-rust = { version = "^0.4" }
directories = { version = "4.0" }
url = { version = "2.2" }
git2 = { version = "0.13.25" }
ansi_term = { version = "0.12" }

7
README.md Normal file
View File

@ -0,0 +1,7 @@
# Theme Control
### Base16 builder and theme applier
See examples for how to use

View File

@ -0,0 +1,9 @@
post = "echo 'after theme apply'"
pre = "echo 'before theme apply'"
[apps]
kitty = "~/kitty.conf"
vim = { file = "~/theme.vim", post = "echo 'after vim theme'", pre = "echo 'before vim theme'" }
test = { file = '~/test', post = "cat $HOME/test" }

View File

@ -0,0 +1,18 @@
scheme: "OceanicNext"
author: "https://github.com/voronianski/oceanic-next-color-scheme"
base00: "1B2B34"
base01: "343D46"
base02: "4F5B66"
base03: "65737E"
base04: "A7ADBA"
base05: "C0C5CE"
base06: "CDD3DE"
base07: "D8DEE9"
base08: "EC5f67"
base09: "F99157"
base0A: "FAC863"
base0B: "99C794"
base0C: "5FB3B3"
base0D: "6699CC"
base0E: "C594C5"
base0F: "AB7967"

View File

@ -0,0 +1,7 @@
[schemes]
local = [ "~/.config/themectl/schemes" ]
sources = [ "https://github.com/chriskempson/base16-schemes-source" ]
[templates]
local = [ "~/.config/themectl/templates" ]
sources = [ "https://github.com/chriskempson/base16-templates-source" ]

View File

@ -0,0 +1,3 @@
{{scheme-name}}
{{base00-hex}}

177
src/builder.rs Normal file
View File

@ -0,0 +1,177 @@
use git2::Repository;
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::path::Path;
use toml::Value;
use yaml_rust::YamlLoader;
pub fn download_sources(data: &Path, store: &Path, cache: &Path) -> Result<(), io::Error> {
if !data.exists() {
fs::create_dir_all(data.parent().unwrap())?; // The unwraps should not be panicking
let mut file = File::create(data)?;
file.write_all(
b"[schemes]
local = [ \"~/.config/themectl/schemes\" ]
sources = [ \"https://github.com/chriskempson/base16-schemes-source\" ]
[templates]
local = [ \"~/.config/themectl/templates\" ]
sources = [ \"https://github.com/chriskempson/base16-templates-source\" ]
",
)?;
}
if !store.exists() {
fs::create_dir_all(store)?;
fs::create_dir_all(store.join("schemes"))?;
fs::create_dir_all(store.join("templates"))?
}
let data = fs::read_to_string(data)?
.parse::<Value>()?;
for source in data
.get("schemes")
.unwrap_or(&Value::String("".to_string()))
.get("sources")
.unwrap_or(&Value::Array([].to_vec()))
.as_array()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect sources format"))?
.iter()
{
let src = source
.as_str()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect sources format"))?;
println!("Retrieving from {}...", src);
git_get(src, &cache.join("schemes"))?;
let yml = yaml_from_file(&cache.join("schemes/list.yaml"))?;
for (_name, url) in yml[0]
.as_hash()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect source list format"))?
.iter() {
git_get(url.as_str().ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect url for source."))?,
&cache.join("gitschemes"))?;
let dict = fs::read_dir(&cache.join("gitschemes"))?
.into_iter()
.filter(|x|
["yml", "yaml"].contains(&(match x.as_ref().unwrap().path().extension() {
Some(a) => a.to_str().unwrap(),
None => "" // All these unwraps shouldn't panic, if they do something is very wrong
})))
.map(|x| x.unwrap().path().into_os_string().into_string().unwrap())
.collect::<Vec<String>>();
for path in dict {
if fs::copy(
path.clone(),
store
.join("schemes")
.join(Path::new(&path).file_name().unwrap()),
)
.is_ok()
{};
}
}
}
for source in data
.get("templates")
.unwrap_or(&Value::String("".to_string()))
.get("sources")
.unwrap_or(&Value::Array([].to_vec()))
.as_array()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect sources format"))?
.iter()
{
let src = source
.as_str()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect sources format"))?;
println!("Retrieving from {}...", src);
git_get(src, &cache.join("template"))?;
let yml = yaml_from_file(&cache.join("template/list.yaml"))?;
for (name, url) in yml[0]
.as_hash()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect source list format"))?
.iter() {
git_get(url.as_str().ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect url for source."))?,
&cache.join("gittemplates"))?;
let dict = fs::read_dir(&cache.join("gittemplates/templates"))?
.into_iter()
.filter(|x|
["mustache"].contains(&(match x.as_ref().unwrap().path().extension() {
Some(a) => a.to_str().unwrap(),
None => "" // All these unwraps shouldn't panic, if they do something is very wrong
})))
.map(|x| x.unwrap().path().into_os_string().into_string().unwrap())
.collect::<Vec<String>>();
for path in dict {
if fs::copy(
path.clone(),
store
.join("templates")
.join(format!("{}-{}", name
.as_str()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect template format"))?,
Path::new(&path).file_name().unwrap().to_str().unwrap()
).replace("-default", "")))
.is_ok()
{};
}
}
}
Ok(())
}
pub fn clean(store: &Path) -> Result<(), io::Error> {
fs::remove_dir_all(store.join("schemes"))?;
fs::remove_dir_all(store.join("templates"))?;
fs::create_dir_all(store.join("schemes"))?;
fs::create_dir_all(store.join("templates"))?;
Ok(())
}
fn git_get(url: &str, path: &Path) -> Result<(), io::Error> {
let dir = path.as_os_str().to_str().ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "Path not found."))?;
if fs::remove_dir_all(dir).is_ok() {};
Repository::clone(url, dir).expect("Failed to clone. ");
Ok(())
}
pub fn yaml_from_file(file: &Path) -> Result<Vec<yaml_rust::Yaml>, io::Error> {
let mut f = File::open(file)?;
let mut string = String::new();
f.read_to_string(&mut string).unwrap();
match YamlLoader::load_from_str(&string) {
Ok(x) => Ok(x),
Err(_) => Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid yaml."))
}
}

85
src/main.rs Normal file
View File

@ -0,0 +1,85 @@
extern crate yaml_rust;
mod builder;
mod theme;
mod preview;
use builder::{clean, download_sources};
use clap::{Parser, Subcommand};
use directories::BaseDirs;
use theme::{apply, list};
use preview::{preview};
// TODO: When accessing elements in the source.toml file, it will panic if it doesn't exist
// TODO: Make error parsing / checking better overall: use ?, return Results and parse them in the
// end and have better error output instead of panic
#[derive(Parser, Debug)]
struct Args {
#[clap(subcommand)]
command: Commands,
}
#[derive(Subcommand, Debug)]
enum Commands {
/// Lists all themes
List {
/// Name of source to list themes from
#[clap(short, long)]
source: Option<String>,
},
/// List all templates
Template {
#[clap(short, long)]
source: Option<String>,
},
/// Applies themes
Apply {
/// Builds files from config and applies a theme of your choice
theme: Option<String>,
},
/// Update sources
Update {},
/// Cleans source directories
Clean {},
/// Preview Colors
Preview {
/// Preview specific theme
#[clap(short, long)]
theme: Option<String>,
}
}
fn main() {
let options = Args::parse();
let base_dirs = BaseDirs::new().expect("Could not find configuration folder."); // Shouldn't happen?
let data_path = base_dirs.data_dir().join("themectl");
let config = base_dirs.config_dir().join("themectl/config.toml");
let sources = base_dirs.config_dir().join("themectl/sources.toml");
let cache = base_dirs.cache_dir().join("themectl");
match &options.command {
Commands::Clean {} => {
clean(&data_path).unwrap();
}
Commands::Update {} => {
download_sources(&sources, &data_path, &cache).unwrap();
}
Commands::Apply { theme } => {
apply(&config, &data_path, &sources, theme).unwrap();
}
Commands::List { source } => {
list(&sources, &data_path, source, "schemes").unwrap();
}
Commands::Template { source } => {
list(&sources, &data_path, source, "templates").unwrap();
}
Commands::Preview { theme } => {
preview(&data_path, &sources, theme.clone()).unwrap();
}
}
}

123
src/preview.rs Normal file
View File

@ -0,0 +1,123 @@
use std::process::Command;
use ansi_term::Color::RGB;
use std::collections::HashMap;
use crate::builder::yaml_from_file;
use std::path::Path;
use std::io;
use std::io::{Read};
use toml::{Value, map::Map};
use std::fs;
pub fn preview(store: &Path, data: &Path, theme: Option<String>) -> Result<(), io::Error> {
if Command::new("clear").status().is_ok() {};
let mut stdin = io::stdin();
let path = match theme {
Some(x) => {
let mut schemes: HashMap<String, String> = HashMap::new();
let data = fs::read_to_string(data)?
.parse::<Value>()?;
for local in data
.get("schemes")
.unwrap_or(&Value::Table(Map::new()))
.get("local")
.unwrap_or(&Value::Array([].to_vec()))
.as_array()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect sources format"))?
.iter()
{
let dict = fs::read_dir(Path::new(
&local.as_str().unwrap().replace("~", env!("HOME")),
))?
.map(|x| String::from(x.unwrap().path().to_str().unwrap()))
.collect::<Vec<String>>();
for i in dict {
schemes.insert(Path::new(&i).file_stem().unwrap().to_str().unwrap().to_string(),
i.clone());
}
}
let dict = fs::read_dir(&store.join("schemes"))?
.map(|x| String::from(x.unwrap().path().to_str().unwrap())) // This shouldn't error
.collect::<Vec<String>>();
for i in dict {
schemes.insert(Path::new(&i).file_stem().unwrap().to_str().unwrap().to_string(),
i.clone());
}
store.join("schemes").join(schemes.get(&x)
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "Invalid theme"))?
)
}
None => store.join("current.yaml")
};
let yaml = &yaml_from_file(&path)?[0];
let mut colors: HashMap<i8, [u8; 3]> = HashMap::new();
for (a, v) in yaml
.as_hash()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Error reading theme file."))?
.iter() {
let val = v.as_str()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Error reading theme file."))?
.to_string();
match a.as_str().unwrap() {
"scheme" => (),
"author" => (),
_ => {
colors.insert(
i8::from_str_radix(
&a.as_str().unwrap()[4..], 16)
.unwrap()
, [
u8::from_str_radix(&val[0..2].to_string(), 16).unwrap(),
u8::from_str_radix(&val[2..4].to_string(), 16).unwrap(),
u8::from_str_radix(&val[4..6].to_string(), 16).unwrap(),
]);
}
}
}
println!();
for i in 0..8 {
print!("{}",
RGB(colors[&i][0], colors[&i][1], colors[&i][2]).on(RGB(colors[&i][0], colors[&i][1], colors[&i][2])).paint(" "));
}
println!();
for i in 0..8 {
print!("{}",
RGB(colors[&i][0], colors[&i][1], colors[&i][2]).on(RGB(colors[&i][0], colors[&i][1], colors[&i][2])).paint(" "));
}
println!();
for i in 8..16 {
print!("{}",
RGB(colors[&i][0], colors[&i][1], colors[&i][2]).on(RGB(colors[&i][0], colors[&i][1], colors[&i][2])).paint(" "));
}
println!();
for i in 8..16 {
print!("{}",
RGB(colors[&i][0], colors[&i][1], colors[&i][2]).on(RGB(colors[&i][0], colors[&i][1], colors[&i][2])).paint(" "));
}
println!();
println!();
stdin.read_exact(&mut [0u8]).unwrap();
Ok(())
}

344
src/theme.rs Normal file
View File

@ -0,0 +1,344 @@
use std::collections::HashMap;
use std::fs;
use std::fs::File;
use std::io::BufWriter;
use std::path::Path;
use std::process::Command;
use toml::{Value, map::Map};
use rustache::{HashBuilder, Render};
use crate::builder::{yaml_from_file};
use std::io;
pub fn apply(config: &Path, store: &Path, data: &Path, source: &Option<String>) -> Result<(), io::Error> {
match source {
Some(st) => {
apply_theme(config, store, data, st.to_string())?;
}
None => {
list(data, store, &None, "schemes")?;
}
}
Ok(())
}
pub fn list(data: &Path, store: &Path, source: &Option<String>, typ: &str) -> Result<(), io::Error> {
let data = fs::read_to_string(data)?
.parse::<Value>()?;
match source {
Some(st) => {
if st == "sources" {
println!("Source {}: ", typ);
let dict = fs::read_dir(&store.join(typ))?
.map(|x| String::from(x.unwrap().path().file_stem().unwrap().to_str().unwrap())) // This shouldn't error
.collect::<Vec<String>>();
for i in dict {
println!(" - {}", i);
}
} else if st == "local" {
println!("Custom {}: ", typ);
for local in data
.get(typ)
.unwrap_or(&Value::Table(Map::new()))
.get("local")
.unwrap_or(&Value::Array([].to_vec()))
.as_array()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect sources format"))?
.iter()
{
let dict = fs::read_dir(Path::new(
&local.as_str().unwrap().replace("~", env!("HOME")),
))?
.map(|x| String::from(x.unwrap().path().file_stem().unwrap().to_str().unwrap()))
.collect::<Vec<String>>();
for i in dict {
println!(" - {}", i);
}
}
} else {
println!("Please use a valid option (sources, local). ");
}
}
None => {
println!("Source {}: ", typ);
let dict = fs::read_dir(&store.join(typ))?
.map(|x| String::from(x.unwrap().path().file_stem().unwrap().to_str().unwrap()))
.collect::<Vec<String>>();
for i in dict {
println!(" - {}", i);
}
println!("\nCustom {}: ", typ);
for local in data
.get(typ)
.unwrap_or(&Value::Table(Map::new()))
.get("local")
.unwrap_or(&Value::Array([].to_vec()))
.as_array()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect sources format"))?
.iter()
{
let dict = fs::read_dir(Path::new(
&local.as_str().unwrap().replace("~", env!("HOME")),
))?
.map(|x| String::from(x.unwrap().path().file_stem().unwrap().to_str().unwrap()))
.collect::<Vec<String>>();
for i in dict {
println!(" - {}", i);
}
}
}
}
Ok(())
}
fn apply_theme(config: &Path, store: &Path, data: &Path, theme: String) -> Result<(), io::Error> {
let config = fs::read_to_string(config)?
.parse::<Value>()?;
let data = fs::read_to_string(data)?
.parse::<Value>()?;
let mut templates: HashMap<String, String> = HashMap::new();
for local in data
.get("templates")
.unwrap_or(&Value::Table(Map::new()))
.get("local")
.unwrap_or(&Value::Array([].to_vec()))
.as_array()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect sources format"))?
.iter()
{
let dict = fs::read_dir(Path::new(
&local.as_str().unwrap().replace("~", env!("HOME")),
))?
.map(|x| String::from(x.unwrap().path().to_str().unwrap()))
.collect::<Vec<String>>();
for i in dict {
templates.insert(Path::new(&i).file_stem().unwrap().to_str().unwrap().to_string(),
i.clone());
}
}
let dict = fs::read_dir(&store.join("templates"))?
.map(|x| String::from(x.unwrap().path().to_str().unwrap())) // This shouldn't error
.collect::<Vec<String>>();
for i in dict {
templates.insert(Path::new(&i).file_stem().unwrap().to_str().unwrap().to_string(),
i.clone());
}
let mut schemes: HashMap<String, String> = HashMap::new();
for local in data
.get("schemes")
.unwrap_or(&Value::Table(Map::new()))
.get("local")
.unwrap_or(&Value::Array([].to_vec()))
.as_array()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Incorrect sources format"))?
.iter()
{
let dict = fs::read_dir(Path::new(
&local.as_str().unwrap().replace("~", env!("HOME")),
))?
.map(|x| String::from(x.unwrap().path().to_str().unwrap()))
.collect::<Vec<String>>();
for i in dict {
schemes.insert(Path::new(&i).file_stem().unwrap().to_str().unwrap().to_string(),
i.clone());
}
}
let dict = fs::read_dir(&store.join("schemes"))?
.map(|x| String::from(x.unwrap().path().to_str().unwrap())) // This shouldn't error
.collect::<Vec<String>>();
for i in dict {
schemes.insert(Path::new(&i).file_stem().unwrap().to_str().unwrap().to_string(),
i.clone());
}
let slug: String = schemes.get(&theme)
.ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "Theme not found."))?
.clone();
fs::copy(Path::new(&slug), &store.join("current.yaml"))?;
let yaml = &yaml_from_file(Path::new(&slug))?[0];
let mut name = String::new();
let mut author = String::new();
let mut colors: HashMap<String, String> = HashMap::new();
for (a, v) in yaml
.as_hash()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Error reading theme file."))?
.iter() {
let val = v.as_str()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Error reading theme file."))?
.to_string();
match a.as_str().unwrap() {
"scheme" => name = val,
"author" => author = val,
_ => {
colors.insert(a.as_str().unwrap().to_string(), val);
}
}
}
if Command::new("sh")
.arg("-c")
.arg(config.get("pre")
.unwrap_or(&Value::String("".to_string()))
.as_str().unwrap_or(""))
.spawn()
.is_ok()
{};
for (key, options) in config.get("apps")
.unwrap_or(&Value::Table(Map::new()))
.as_table()
.unwrap()
.into_iter() {
let key = key.as_str();
let file = match options.as_table() {
Some(v) => v.get("file")
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, format!("Couldn't find file option for {}",key)))?
.as_str()
.unwrap()
.replace("~", env!("HOME")),
None => options.as_str()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, format!("Couldn't find file option for {}",key)))?
.replace("~", env!("HOME")),
};
// We have key -> Here check if key exists as a name in templates variable (String: String)
// where it is TemplateName: TemplateFile
templates.keys()
.find(|&x| key == x)
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, format!("No key found: {}", key)))?;
if Command::new("sh")
.arg("-c")
.arg(options
.as_table()
.unwrap_or(&Map::new())
.get("pre")
.unwrap_or(&Value::String("".to_string()))
.as_str()
.unwrap_or(""))
.spawn()
.is_ok()
{};
// Here we want to parse the mustache file, and write it to the final file
// (open template file + save mustache to string)
// Copy in base16 colors in
// Write to `file` variable
let mustache = fs::read_to_string(templates.get(key).unwrap())?; // shouldn't error
// Need to detect these errors
let mut musthash = HashBuilder::new();
musthash = musthash.insert("scheme-slug", slug.as_ref());
musthash = musthash.insert("scheme-name", name.as_ref());
musthash = musthash.insert("scheme-author", author.as_ref());
for (b, c) in &colors {
musthash = musthash.insert(b.to_string() + "-hex", c.as_ref());
let red = c[0..2].to_string();
musthash = musthash.insert(b.to_string() + "-hex-r", red.as_ref());
let red = i32::from_str_radix(c[0..2].as_ref(), 16).unwrap();
musthash = musthash.insert(b.to_string() + "-rgb-r", red);
musthash = musthash.insert(b.to_string() + "-dec-r", red as f64 / 255.0);
let green = c[2..4].to_string();
musthash = musthash.insert(b.to_string() + "-hex-g", green.as_ref());
let green = i32::from_str_radix(c[2..4].as_ref(), 16).unwrap();
musthash = musthash.insert(b.to_string() + "-rgb-g", green);
musthash = musthash.insert(b.to_string() + "-dec-g", green as f64 / 255.0);
let blue = c[4..6].to_string();
musthash = musthash.insert(b.to_string() + "-hex-b", blue.as_ref());
let blue = i32::from_str_radix(c[4..6].as_ref(), 16).unwrap();
musthash = musthash.insert(b.to_string() + "-rgb-b", blue);
musthash = musthash.insert(b.to_string() + "-dec-b", blue as f64 / 255.0);
musthash = musthash.insert(
b.to_string() + "-hex-bgr",
format!("{}{}{}", blue, green, red),
);
}
if let Some(x) = Path::new(file.clone().as_str()).parent() {
fs::create_dir_all(x)?
};
let f = File::create(file.clone())?;
let mut out = BufWriter::new(f);
musthash.render(&mustache, &mut out)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid template format."))?;
if Command::new("sh")
.arg("-c")
.arg(options
.as_table()
.unwrap_or(&Map::new())
.get("post")
.unwrap_or(&Value::String("".to_string()))
.as_str()
.unwrap_or(""))
.spawn()
.is_ok()
{};
};
if Command::new("sh")
.arg("-c")
.arg(config.get("post")
.unwrap_or(&Value::String("".to_string()))
.as_str().unwrap_or(""))
.spawn()
.is_ok()
{};
Ok(())
}