diff --git a/Cargo.lock b/Cargo.lock index 240dc241..d4dca7a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,21 +11,6 @@ dependencies = [ "memchr", ] -[[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 = "ansi_colours" version = "1.2.2" @@ -47,18 +32,185 @@ dependencies = [ "num-traits", ] +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand 2.1.0", + "futures-lite 2.3.0", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io 2.3.3", + "async-lock 3.4.0", + "blocking", + "futures-lite 2.3.0", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" +dependencies = [ + "async-lock 3.4.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.3.0", + "parking", + "polling 3.7.2", + "rustix 0.38.34", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io 1.13.0", + "async-lock 2.8.0", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite 1.13.0", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite 2.3.0", + "piper", +] + [[package]] name = "bpaf" version = "0.9.12" @@ -81,12 +233,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" -[[package]] -name = "cc" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" - [[package]] name = "cfg-if" version = "1.0.0" @@ -94,22 +240,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "chrono" -version = "0.4.38" +name = "concurrent-queue" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "windows-targets 0.52.5", + "crossbeam-utils", ] [[package]] -name = "core-foundation-sys" -version = "0.8.6" +name = "crossbeam-utils" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.6.0", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] [[package]] name = "deranged" @@ -117,6 +285,7 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ + "powerfmt", "serde", ] @@ -166,18 +335,103 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + [[package]] name = "fast-srgb8" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand 2.1.0", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -189,6 +443,18 @@ dependencies = [ "wasi", ] +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -201,6 +467,18 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hyfetch" version = "1.4.11" @@ -209,7 +487,6 @@ dependencies = [ "ansi_colours", "anyhow", "bpaf", - "chrono", "deranged", "directories", "enable-ansi-support", @@ -222,37 +499,18 @@ dependencies = [ "serde_path_to_error", "shell-words", "strum", + "supports-color", "tempfile", + "termbg", + "terminal_size", "thiserror", + "time", "tracing", "tracing-subscriber", "unicode-normalization", "unicode-segmentation", ] -[[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 = "indexmap" version = "2.2.6" @@ -264,6 +522,37 @@ dependencies = [ "serde", ] +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "is_ci" version = "1.2.0" @@ -285,6 +574,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -303,21 +601,40 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags", + "bitflags 2.6.0", "libc", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + [[package]] name = "linux-raw-sys" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -325,6 +642,18 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "normpath" version = "1.2.0" @@ -344,6 +673,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" version = "0.2.19" @@ -353,6 +688,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -400,12 +744,95 @@ dependencies = [ "syn", ] +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.5", +] + [[package]] name = "pin-project-lite" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" +dependencies = [ + "atomic-waker", + "fastrand 2.1.0", + "futures-io", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix 0.38.34", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro2" version = "1.0.86" @@ -424,6 +851,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "redox_users" version = "0.4.5" @@ -464,16 +900,30 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + [[package]] name = "rustix" version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] @@ -489,6 +939,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.203" @@ -545,12 +1001,61 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "strum" version = "0.26.3" @@ -600,11 +1105,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand", - "rustix", + "fastrand 2.1.0", + "rustix 0.38.34", "windows-sys 0.52.0", ] +[[package]] +name = "termbg" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c12e6e0bf9bc6ac887681aeddabfcc5dbdea20d3f43d6d18f237c34fe942dde" +dependencies = [ + "async-std", + "crossterm", + "is-terminal", + "thiserror", + "winapi", +] + +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix 0.38.34", + "windows-sys 0.48.0", +] + [[package]] name = "thiserror" version = "1.0.61" @@ -635,6 +1163,27 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + [[package]] name = "tinyvec" version = "1.6.1" @@ -734,6 +1283,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -765,6 +1326,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.92" @@ -794,6 +1367,16 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -816,15 +1399,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.5", -] - [[package]] name = "windows-sys" version = "0.42.0" diff --git a/Cargo.toml b/Cargo.toml index 7c0e589d..d6470846 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,10 +14,8 @@ license = "MIT" [workspace.dependencies] aho-corasick = { version = "1.1.3", default-features = false } ansi_colours = { version = "1.2.2", default-features = false } -# anstream = { version = "0.6.14", default-features = false } anyhow = { version = "1.0.86", default-features = false } bpaf = { version = "0.9.12", default-features = false } -chrono = { version = "0.4.38", default-features = false } deranged = { version = "0.3.11", default-features = false } directories = { version = "5.0.1", default-features = false } enable-ansi-support = { version = "0.2.1", default-features = false } @@ -30,8 +28,12 @@ serde_json = { version = "1.0.118", default-features = false } serde_path_to_error = { version = "0.1.16", default-features = false } shell-words = { version = "1.1.0", default-features = false } strum = { version = "0.26.3", default-features = false } +supports-color = { version = "3.0.0", default-features = false } tempfile = { version = "3.10.1", default-features = false } +termbg = { version = "0.5.0", default-features = false } +terminal_size = { version = "0.3.0", default-features = false } thiserror = { version = "1.0.61", default-features = false } +time = { version = "0.3.36", default-features = false } tracing = { version = "0.1.40", default-features = false } tracing-subscriber = { version = "0.3.18", default-features = false } unicode-normalization = { version = "0.1.23", default-features = false } diff --git a/crates/hyfetch/Cargo.toml b/crates/hyfetch/Cargo.toml index 2ec896a0..42efb6d8 100644 --- a/crates/hyfetch/Cargo.toml +++ b/crates/hyfetch/Cargo.toml @@ -12,10 +12,8 @@ default-run = "hyfetch" [dependencies] aho-corasick = { workspace = true, features = ["perf-literal", "std"] } ansi_colours = { workspace = true, features = [] } -# anstream = { workspace = true, features = ["auto"] } anyhow = { workspace = true, features = ["std"] } bpaf = { workspace = true, features = [] } -chrono = { workspace = true, features = ["clock", "std"] } deranged = { workspace = true, features = ["serde", "std"] } directories = { workspace = true, features = [] } indexmap = { workspace = true, features = ["serde", "std"] } @@ -25,8 +23,12 @@ serde_json = { workspace = true, features = ["std"] } serde_path_to_error = { workspace = true, features = [] } shell-words = { workspace = true, features = ["std"] } strum = { workspace = true, features = ["derive", "std"] } +supports-color = { workspace = true, features = [] } tempfile = { workspace = true, features = [] } +termbg = { workspace = true, features = [] } +terminal_size = { workspace = true, features = [] } thiserror = { workspace = true, features = [] } +time = { workspace = true, features = ["local-offset", "std"] } tracing = { workspace = true, features = ["attributes", "std"] } tracing-subscriber = { workspace = true, features = ["ansi", "fmt", "smallvec", "std", "tracing-log"] } unicode-segmentation = { workspace = true, features = [] } diff --git a/crates/hyfetch/src/bin/hyfetch.rs b/crates/hyfetch/src/bin/hyfetch.rs index c23670d5..0080c8b7 100644 --- a/crates/hyfetch/src/bin/hyfetch.rs +++ b/crates/hyfetch/src/bin/hyfetch.rs @@ -1,17 +1,23 @@ -use std::fmt; +use std::borrow::Cow; +use std::cmp; use std::fs::{self, File}; use std::io::{self, ErrorKind, IsTerminal, Read}; use std::path::Path; use anyhow::{Context, Result}; -use chrono::Datelike; use hyfetch::cli_options::options; +use hyfetch::color_util::{clear_screen, color, printc, ForegroundBackground, Theme}; use hyfetch::models::Config; #[cfg(windows)] use hyfetch::neofetch_util::ensure_git_bash; -use hyfetch::neofetch_util::{self, get_distro_ascii, ColorAlignment}; -use hyfetch::presets::AssignLightness; +use hyfetch::neofetch_util::{self, ascii_size, get_distro_ascii, ColorAlignment}; +use hyfetch::presets::{AssignLightness, Preset}; +use hyfetch::types::{AnsiMode, LightDark}; use hyfetch::utils::get_cache_path; +use palette::Srgb; +use strum::{EnumCount, VariantArray, VariantNames}; +use terminal_size::terminal_size; +use time::{Month, OffsetDateTime}; use tracing::debug; fn main() -> Result<()> { @@ -39,21 +45,24 @@ fn main() -> Result<()> { } let config = if options.config { - create_config(options.config_file).context("failed to create config")? + create_config(distro, &options.config_file, options.debug) + .context("failed to create config")? } else if let Some(config) = read_config(&options.config_file).context("failed to read config")? { config } else { - create_config(options.config_file).context("failed to create config")? + create_config(distro, &options.config_file, options.debug) + .context("failed to create config")? }; // Check if it's June (pride month) - let now = chrono::Local::now(); + let now = + OffsetDateTime::now_local().context("failed to get current datetime in local timezone")?; let cache_path = get_cache_path().context("failed to get cache path")?; let june_path = cache_path.join(format!("animation-displayed-{}", now.year())); - let show_pride_month = - options.june || now.month() == 6 && !june_path.is_file() && io::stdout().is_terminal(); + let show_pride_month = options.june + || now.month() == Month::June && !june_path.is_file() && io::stdout().is_terminal(); if show_pride_month && !config.pride_month_disable { // TODO @@ -134,12 +143,7 @@ fn main() -> Result<()> { /// /// Returns `None` if the config file does not exist. #[tracing::instrument(level = "debug")] -fn read_config

(path: P) -> Result> -where - P: AsRef + fmt::Debug, -{ - let path = path.as_ref(); - +fn read_config(path: &Path) -> Result> { let mut file = match File::open(path) { Ok(file) => file, Err(err) if err.kind() == ErrorKind::NotFound => { @@ -168,10 +172,229 @@ where /// /// The config is automatically stored to file. #[tracing::instrument(level = "debug")] -fn create_config

(path: P) -> Result -where - P: AsRef + fmt::Debug, -{ +fn create_config(distro: Option<&String>, path: &Path, debug_: bool) -> Result { + // Detect terminal environment (doesn't work for all terminal emulators, + // especially on Windows) + let det_bg = match termbg::rgb(std::time::Duration::from_millis(100)) { + Ok(rgb) => Some(Srgb::::new(rgb.r, rgb.g, rgb.b).into_format::()), + Err(termbg::Error::Unsupported) => None, + Err(err) => { + return Err(err).context("failed to get background color"); + }, + }; + debug!(?det_bg, "detected background color"); + let det_ansi = supports_color::on(supports_color::Stream::Stdout).map(|color_level| { + if color_level.has_16m { + AnsiMode::Rgb + } else if color_level.has_256 { + AnsiMode::Ansi256 + } else if color_level.has_basic { + AnsiMode::Ansi16 + } else { + unreachable!(); + } + }); + debug!(?det_ansi, "detected color mode"); + + let (asc, fore_back) = get_distro_ascii(distro).context("failed to get distro ascii")?; + let (asc_width, asc_lines) = ascii_size(asc); + let theme = det_bg.map(|bg| bg.theme()).unwrap_or(LightDark::Light); + let color_mode = det_ansi.unwrap_or(AnsiMode::Ansi256); + let logo = color( + match theme { + LightDark::Light => "&l&bhyfetch&~&L", + LightDark::Dark => "&l&bhy&ffetch&~&L", + }, + color_mode, + ) + .expect("logo should not contain invalid color codes"); + let mut title = format!("Welcome to {logo} Let's set up some colors first."); + clear_screen(Some(&title), color_mode, debug_) + .expect("title should not contain invalid color codes"); + + let mut option_counter: u8 = 1; + + fn update_title(title: &mut String, option_counter: &mut u8, k: &str, v: &str) { + let k: Cow = if k.ends_with(':') { + k.into() + } else { + format!("{k}:").into() + }; + title.push_str({ + let pad = " ".repeat(30 - k.len()); + &format!("\n&e{option_counter}. {k}{pad} &~{v}") + }); + *option_counter += 1; + } + + fn print_title_prompt(option_counter: u8, prompt: &str, color_mode: AnsiMode) { + printc(format!("&a{option_counter}. {prompt}"), color_mode) + .expect("prompt should not contain invalid color codes"); + } + + ////////////////////////////// + // 0. Check term size + + // TODO + + ////////////////////////////// + // 1. Select color system + let select_color_system = || -> Result<(AnsiMode, &str)> { + if det_ansi == Some(AnsiMode::Rgb) { + return Ok((AnsiMode::Rgb, "Detected color mode")); + } + + clear_screen(Some(&title), color_mode, debug_) + .expect("title should not contain invalid color codes"); + + // TODO + + println!(); + print_title_prompt( + option_counter, + "Which &bcolor system &ado you want to use?", + color_mode, + ); + printc( + r#"(If you can't see colors under "RGB Color Testing", please choose 8bit)"#, + color_mode, + ) + .expect("message should not contain invalid color codes"); + println!(); + + todo!() + }; + + let color_mode = { + let (color_system, ttl) = select_color_system().context("failed to select color system")?; + debug!(?color_system, "selected color mode"); + update_title(&mut title, &mut option_counter, ttl, color_system.into()); + color_system + }; + + ////////////////////////////// + // 2. Select light/dark mode + let select_light_dark = || -> Result<(LightDark, &str)> { + if let Some(det_bg) = det_bg { + return Ok((det_bg.theme(), "Detected background color")); + } + + clear_screen(Some(&title), color_mode, debug_) + .expect("title should not contain invalid color codes"); + + todo!() + }; + + let theme = { + let (light_dark, ttl) = + select_light_dark().context("failed to select light / dark mode")?; + debug!(?light_dark, "selected theme"); + update_title(&mut title, &mut option_counter, ttl, light_dark.into()); + light_dark + }; + + ////////////////////////////// + // 3. Choose preset + // Create flag lines + let mut flags = Vec::with_capacity(Preset::COUNT); + let spacing = { + let Some(spacing) = ::VARIANTS + .iter() + .map(|name| name.chars().count()) + .max() + else { + unreachable!(); + }; + let spacing: u8 = spacing.try_into().expect("`spacing` should fit in `u8`"); + cmp::max(spacing, 20) + }; + for preset in ::VARIANTS { + let color_profile = preset.color_profile(); + let flag = color_profile + .color_text( + " ".repeat(spacing as usize), + color_mode, + ForegroundBackground::Background, + false, + ) + .with_context(|| format!("failed to color flag using preset: {preset:?}"))?; + let name = { + let name: &'static str = preset.into(); + let name_len = name.chars().count(); + let name_len: u8 = name_len.try_into().expect("`name_len` should fit in `u8`"); + let pad_start = " ".repeat(((spacing - name_len) / 2) as usize); + let pad_end = + " ".repeat(((spacing - name_len) / 2 + (spacing - name_len) % 2) as usize); + format!("{pad_start}{name}{pad_end}") + }; + flags.push([name, flag.clone(), flag.clone(), flag]); + } + + // Calculate flags per row + let (flags_per_row, rows_per_page) = { + let (term_w, term_h) = terminal_size().context("failed to get terminal size")?; + let flags_per_row = term_w.0 / (spacing as u16 + 2); + let flags_per_row: u8 = flags_per_row + .try_into() + .expect("`flags_per_row` should fit in `u8`"); + let rows_per_page = ((term_h.0 - 13) as f32 / 5.0).floor() as usize; + let rows_per_page: u8 = rows_per_page + .try_into() + .expect("`rows_per_page` should fit in `u8`"); + let rows_per_page = cmp::max(1, rows_per_page); + (flags_per_row, rows_per_page) + }; + let num_pages = (Preset::COUNT as f32 / (flags_per_row * rows_per_page) as f32).ceil() as usize; + let num_pages: u8 = num_pages + .try_into() + .expect("`num_pages` should fit in `u8`"); + + // Create pages + let mut pages = Vec::with_capacity(num_pages as usize); + for flags in flags.chunks((flags_per_row * rows_per_page) as usize) { + let mut page = Vec::with_capacity(rows_per_page as usize); + for flags in flags.chunks(flags_per_row as usize) { + page.push(flags); + } + pages.push(page); + } + + let print_flag_row = |row: &[[String; 4]]| { + for i in 0..4 { + let mut line = String::new(); + for flag in row { + line.push_str(&flag[i]); + line.push_str(" "); + } + printc(line, color_mode).expect("flag line should not contain invalid color codes"); + } + println!(); + }; + + let print_flag_page = |page, page_num| { + clear_screen(Some(&title), color_mode, debug_) + .expect("title should not contain invalid color codes"); + print_title_prompt(option_counter, "Let's choose a flag!", color_mode); + printc("Available flag presets:", color_mode) + .expect("prompt should not contain invalid color codes"); + { + let page_num = page_num + 1; + println!("Page: {page_num} of {num_pages}"); + } + println!(); + for &row in page { + print_flag_row(row); + } + println!(); + }; + + let page: u8 = 0; + loop { + print_flag_page(&pages[page as usize], page); + + todo!(); + } + todo!() } diff --git a/crates/hyfetch/src/color_util.rs b/crates/hyfetch/src/color_util.rs index d9db8d2c..541cc0e8 100644 --- a/crates/hyfetch/src/color_util.rs +++ b/crates/hyfetch/src/color_util.rs @@ -6,11 +6,11 @@ use aho_corasick::AhoCorasick; use ansi_colours::AsRGB; use anyhow::{anyhow, Context, Result}; use deranged::RangedU8; -use palette::Srgb; +use palette::{IntoColorMut, LinSrgb, Okhsl, Srgb}; use serde::{Deserialize, Serialize}; use thiserror::Error; -use crate::types::AnsiMode; +use crate::types::{AnsiMode, LightDark}; const MINECRAFT_COLORS: [(&str, &str); 30] = [ // Minecraft formatting codes @@ -53,10 +53,12 @@ const RGB_COLOR_PATTERNS: [&str; 2] = ["&gf(", "&gb("]; static MINECRAFT_COLORS_AC: OnceLock<(AhoCorasick, Box<[&str; 30]>)> = OnceLock::new(); static RGB_COLORS_AC: OnceLock = OnceLock::new(); -/// Represents the lightness component in HSL. +/// Represents the lightness component in [`Okhsl`]. /// /// The range of valid values is /// `(`[`Lightness::MIN`]`..=`[`Lightness::MAX`]`)`. +/// +/// [`Okhsl`]: palette::Okhsl #[derive(Copy, Clone, PartialEq, PartialOrd, Debug, Deserialize, Serialize)] pub struct Lightness(f32); @@ -110,9 +112,13 @@ pub trait ToAnsiString { -> String; } +pub trait Theme { + fn theme(&self) -> LightDark; +} + impl Lightness { - const MAX: f32 = 1.0f32; - const MIN: f32 = 0.0f32; + pub const MAX: f32 = 1.0f32; + pub const MIN: f32 = 0.0f32; pub fn new(value: f32) -> Result { if !(Self::MIN..=Self::MAX).contains(&value) { @@ -146,8 +152,8 @@ impl From for f32 { } impl NeofetchAsciiIndexedColor { - const MAX: u8 = 6; - const MIN: u8 = 1; + pub const MAX: u8 = 6; + pub const MIN: u8 = 1; } impl TryFrom for NeofetchAsciiIndexedColor { @@ -212,6 +218,25 @@ impl ToAnsiString for Srgb { let indexed = rgb.to_ansi256(); format!("\x1b[{c};5;{indexed}m") }, + AnsiMode::Ansi16 => { + unimplemented!(); + }, + } + } +} + +impl Theme for Srgb { + fn theme(&self) -> LightDark { + let mut rgb_f32_color: LinSrgb = self.into_linear(); + + { + let okhsl_f32_color: &mut Okhsl = &mut rgb_f32_color.into_color_mut(); + + if okhsl_f32_color.lightness > 0.5 { + LightDark::Light + } else { + LightDark::Dark + } } } } @@ -311,3 +336,31 @@ where Ok(dst) } + +pub fn printc(msg: S, mode: AnsiMode) -> Result<()> +where + S: AsRef, +{ + let msg = msg.as_ref(); + + println!( + "{}", + color(format!("{msg}&r"), mode).context("failed to color message")? + ); + + Ok(()) +} + +pub fn clear_screen(title: Option<&str>, mode: AnsiMode, debug: bool) -> Result<()> { + if !debug { + print!("\x1b[2J\x1b[H"); + } + + if let Some(title) = title { + println!(); + printc(title, mode).context("failed to color title")?; + println!(); + } + + Ok(()) +} diff --git a/crates/hyfetch/src/presets.rs b/crates/hyfetch/src/presets.rs index 3ee6a475..ecabc60d 100644 --- a/crates/hyfetch/src/presets.rs +++ b/crates/hyfetch/src/presets.rs @@ -2,88 +2,158 @@ use std::iter; use anyhow::{anyhow, Context, Result}; use indexmap::IndexSet; -use palette::encoding::{self, Linear}; use palette::num::ClampAssign; -use palette::{Hsl, IntoColorMut, LinSrgb, Srgb}; +use palette::{IntoColorMut, LinSrgb, Okhsl, Srgb}; use serde::{Deserialize, Serialize}; -use strum::{EnumString, VariantNames}; +use strum::{EnumCount, EnumString, IntoStaticStr, VariantArray, VariantNames}; use tracing::debug; use unicode_segmentation::UnicodeSegmentation; use crate::color_util::{ForegroundBackground, Lightness, ToAnsiString}; use crate::types::{AnsiMode, LightDark}; -#[derive(Copy, Clone, Hash, Debug, Deserialize, EnumString, Serialize, VariantNames)] +#[derive( + Copy, + Clone, + Hash, + Debug, + Deserialize, + EnumCount, + EnumString, + IntoStaticStr, + Serialize, + VariantArray, + VariantNames, +)] #[serde(rename_all = "kebab-case")] #[strum(serialize_all = "kebab-case")] pub enum Preset { - Abrosexual, + Rainbow, + + Transgender, + + Nonbinary, + + Xenogender, + Agender, - Akiosexual, - Androsexual, - Aroace1, - Aroace2, - Aroace3, - Aromantic, - Asexual, - Autoromantic, - Autosexual, - /// Colors from Gilbert Baker's original 1978 flag design - Baker, - /// Meme flag - Beiyang, - Bigender, - Biromantic1, - Bisexual, - Boyflux2, - /// Meme flag - Burger, - Demiboy, - Demifae, - Demifaun, - Demigender, - Demigirl, - Femboy, - Finsexual, - Fraysexual, - GayMen, - Genderfae, - Genderfaun, + + Queer, + Genderfluid, + + Bisexual, + + Pansexual, + + Polysexual, + + Omnisexual, + + Omniromantic, + + GayMen, + + Lesbian, + + Abrosexual, + + Asexual, + + Aromantic, + + Aroace1, + + Aroace2, + + Aroace3, + + Greysexual, + + Autosexual, + + Intergender, + + Greygender, + + Akiosexual, + + Bigender, + + Demigender, + + Demiboy, + + Demigirl, + + Transmasculine, + + Transfeminine, + + Genderfaun, + + Demifaun, + + Genderfae, + + Demifae, + + Neutrois, + + Biromantic1, + + Autoromantic, + + Boyflux2, + + Girlflux, + Genderflux, + + Finsexual, + + Unlabeled1, + + Unlabeled2, + + Pangender, + #[serde(rename = "gendernonconforming1")] #[strum(serialize = "gendernonconforming1")] GenderNonconforming1, + #[serde(rename = "gendernonconforming2")] #[strum(serialize = "gendernonconforming2")] GenderNonconforming2, - Gendervoid, - Girlflux, - Greygender, - Greysexual, - Gynesexual, - Intergender, - Lesbian, - Neutrois, - Nonbinary, - NonhumanUnity, - Omniromantic, - Omnisexual, - Pangender, - Pansexual, - Plural, - Polysexual, - Queer, - Rainbow, + + Femboy, + Tomboy, - Transfeminine, - Transgender, - Transmasculine, - Unlabeled1, - Unlabeled2, - Voidboy, + + Gynesexual, + + Androsexual, + + Gendervoid, + Voidgirl, - Xenogender, + + Voidboy, + + NonhumanUnity, + + Plural, + + Fraysexual, + + /// Meme flag + Beiyang, + + /// Meme flag + Burger, + + /// Colors from Gilbert Baker's original 1978 flag design + Baker, } #[derive(Clone, Eq, PartialEq, Debug)] @@ -101,25 +171,72 @@ pub enum AssignLightness { impl Preset { pub fn color_profile(&self) -> ColorProfile { (match self { - // used colorpicker to source from https://fyeahaltpride.tumblr.com/post/151704251345/could-you-guys-possibly-make-an-abrosexual-pride - Self::Abrosexual => ColorProfile::from_hex_colors(vec![ - "#46D294", "#A3E9CA", "#FFFFFF", "#F78BB3", "#EE1766", + Self::Rainbow => ColorProfile::from_hex_colors(vec![ + "#E50000", "#FF8D00", "#FFEE00", "#028121", "#004CFF", "#770088", + ]), + + Self::Transgender => ColorProfile::from_hex_colors(vec![ + "#55CDFD", "#F6AAB7", "#FFFFFF", "#F6AAB7", "#55CDFD", + ]), + + Self::Nonbinary => { + ColorProfile::from_hex_colors(vec!["#FCF431", "#FCFCFC", "#9D59D2", "#282828"]) + }, + + // sourced from https://commons.wikimedia.org/wiki/File:Xenogender_pride_flag.svg + Self::Xenogender => ColorProfile::from_hex_colors(vec![ + "#FF6692", "#FF9A98", "#FFB883", "#FBFFA8", "#85BCFF", "#9D85FF", "#A510FF", ]), Self::Agender => ColorProfile::from_hex_colors(vec![ "#000000", "#BABABA", "#FFFFFF", "#BAF484", "#FFFFFF", "#BABABA", "#000000", ]), - // sourced from https://www.flagcolorcodes.com/akiosexual - Self::Akiosexual => ColorProfile::from_hex_colors(vec![ - "#F9485E", "#FEA06A", "#FEF44C", "#FFFFFF", "#000000", + Self::Queer => ColorProfile::from_hex_colors(vec!["#B57FDD", "#FFFFFF", "#49821E"]), + + Self::Genderfluid => ColorProfile::from_hex_colors(vec![ + "#FE76A2", "#FFFFFF", "#BF12D7", "#000000", "#303CBE", ]), - // sourced from https://lgbtqia.fandom.com/wiki/Androsexual - Self::Androsexual => { - ColorProfile::from_hex_colors(vec!["#01CCFF", "#603524", "#B799DE"]) + Self::Bisexual => ColorProfile::from_hex_colors(vec!["#D60270", "#9B4F96", "#0038A8"]), + + Self::Pansexual => ColorProfile::from_hex_colors(vec!["#FF1C8D", "#FFD700", "#1AB3FF"]), + + Self::Polysexual => { + ColorProfile::from_hex_colors(vec!["#F714BA", "#01D66A", "#1594F6"]) }, + // sourced from https://www.flagcolorcodes.com/omnisexual + Self::Omnisexual => ColorProfile::from_hex_colors(vec![ + "#FE9ACE", "#FF53BF", "#200044", "#6760FE", "#8EA6FF", + ]), + + Self::Omniromantic => ColorProfile::from_hex_colors(vec![ + "#FEC8E4", "#FDA1DB", "#89739A", "#ABA7FE", "#BFCEFF", + ]), + + // sourced from https://www.flagcolorcodes.com/gay-men + Self::GayMen => ColorProfile::from_hex_colors(vec![ + "#078D70", "#98E8C1", "#FFFFFF", "#7BADE2", "#3D1A78", + ]), + + Self::Lesbian => ColorProfile::from_hex_colors(vec![ + "#D62800", "#FF9B56", "#FFFFFF", "#D462A6", "#A40062", + ]), + + // used colorpicker to source from https://fyeahaltpride.tumblr.com/post/151704251345/could-you-guys-possibly-make-an-abrosexual-pride + Self::Abrosexual => ColorProfile::from_hex_colors(vec![ + "#46D294", "#A3E9CA", "#FFFFFF", "#F78BB3", "#EE1766", + ]), + + Self::Asexual => { + ColorProfile::from_hex_colors(vec!["#000000", "#A4A4A4", "#FFFFFF", "#810081"]) + }, + + Self::Aromantic => ColorProfile::from_hex_colors(vec![ + "#3BA740", "#A8D47A", "#FFFFFF", "#ABABAB", "#000000", + ]), + // sourced from https://flag.library.lgbt/flags/aroace/ Self::Aroace1 => ColorProfile::from_hex_colors(vec![ "#E28C00", "#ECCD00", "#FFFFFF", "#62AEDC", "#203856", @@ -136,32 +253,29 @@ impl Preset { "#810081", ]), - Self::Aromantic => ColorProfile::from_hex_colors(vec![ - "#3BA740", "#A8D47A", "#FFFFFF", "#ABABAB", "#000000", + // sourced from https://www.flagcolorcodes.com/greysexual + Self::Greysexual => ColorProfile::from_hex_colors(vec![ + "#740194", "#AEB1AA", "#FFFFFF", "#AEB1AA", "#740194", ]), - Self::Asexual => { - ColorProfile::from_hex_colors(vec!["#000000", "#A4A4A4", "#FFFFFF", "#810081"]) - }, - - // sourced from https://www.flagcolorcodes.com/autoromantic - Self::Autoromantic => ColorProfile::from_hex_colors( - // symbol interpreted - vec!["#99D9EA", "#3DA542", "#7F7F7F"], - ) - .and_then(|c| c.with_weights(vec![2, 1, 2])), - // sourced from https://www.flagcolorcodes.com/autosexual Self::Autosexual => ColorProfile::from_hex_colors(vec!["#99D9EA", "#7F7F7F"]), - // used https://gilbertbaker.com/rainbow-flag-color-meanings/ as source and colorpicked - Self::Baker => ColorProfile::from_hex_colors(vec![ - "#F23D9E", "#F80A24", "#F78022", "#F9E81F", "#1E972E", "#1B86BC", "#243897", - "#6F0A82", - ]), + // sourced from https://www.flagcolorcodes.com/intergender + Self::Intergender => { + ColorProfile::from_hex_colors(vec!["#900DC2", "#FFE54F", "#900DC2"]) + .and_then(|c| c.with_weights(vec![2, 1, 2])) + }, - Self::Beiyang => ColorProfile::from_hex_colors(vec![ - "#DF1B12", "#FFC600", "#01639D", "#FFFFFF", "#000000", + // sourced from https://www.flagcolorcodes.com/greygender + Self::Greygender => ColorProfile::from_hex_colors(vec![ + "#B3B3B3", "#FFFFFF", "#062383", "#FFFFFF", "#535353", + ]) + .and_then(|c| c.with_weights(vec![2, 1, 2, 1, 2])), + + // sourced from https://www.flagcolorcodes.com/akiosexual + Self::Akiosexual => ColorProfile::from_hex_colors(vec![ + "#F9485E", "#FEA06A", "#FEF44C", "#FFFFFF", "#000000", ]), // sourced from https://www.flagcolorcodes.com/bigender @@ -169,22 +283,10 @@ impl Preset { "#C479A2", "#EDA5CD", "#D6C7E8", "#FFFFFF", "#D6C7E8", "#9AC7E8", "#6D82D1", ]), - // sourced from https://www.flagcolorcodes.com/biromantic-alternate-2 - Self::Biromantic1 => ColorProfile::from_hex_colors(vec![ - "#8869A5", "#D8A7D8", "#FFFFFF", "#FDB18D", "#151638", - ]), - - Self::Bisexual => ColorProfile::from_hex_colors(vec!["#D60270", "#9B4F96", "#0038A8"]), - - // sourced from https://www.flagcolorcodes.com/boyflux-alternate-2 - Self::Boyflux2 => ColorProfile::from_hex_colors(vec![ - "#E48AE4", "#9A81B4", "#55BFAB", "#FFFFFF", "#A8A8A8", "#81D5EF", "#69ABE5", - "#5276D4", - ]) - .and_then(|c| c.with_weights(vec![1, 1, 1, 1, 1, 5, 5, 5])), - - Self::Burger => ColorProfile::from_hex_colors(vec![ - "#F3A26A", "#498701", "#FD1C13", "#7D3829", "#F3A26A", + // yellow sourced from https://lgbtqia.fandom.com/f/p/4400000000000041031 + // other colors sourced from demiboy and demigirl flags + Self::Demigender => ColorProfile::from_hex_colors(vec![ + "#7F7F7F", "#C4C4C4", "#FBFF75", "#FFFFFF", "#FBFF75", "#C4C4C4", "#7F7F7F", ]), // sourced from https://www.flagcolorcodes.com/demiboy @@ -192,6 +294,39 @@ impl Preset { "#7F7F7F", "#C4C4C4", "#9DD7EA", "#FFFFFF", "#9DD7EA", "#C4C4C4", "#7F7F7F", ]), + // sourced from https://www.flagcolorcodes.com/demigirl + Self::Demigirl => ColorProfile::from_hex_colors(vec![ + "#7F7F7F", "#C4C4C4", "#FDADC8", "#FFFFFF", "#FDADC8", "#C4C4C4", "#7F7F7F", + ]), + + // sourced from https://www.flagcolorcodes.com/transmasculine + Self::Transmasculine => ColorProfile::from_hex_colors(vec![ + "#FF8ABD", "#CDF5FE", "#9AEBFF", "#74DFFF", "#9AEBFF", "#CDF5FE", "#FF8ABD", + ]), + + // used colorpicker to source from https://www.deviantart.com/pride-flags/art/Trans-Woman-Transfeminine-1-543925985 + // linked from https://gender.fandom.com/wiki/Transfeminine + Self::Transfeminine => ColorProfile::from_hex_colors(vec![ + "#73DEFF", "#FFE2EE", "#FFB5D6", "#FF8DC0", "#FFB5D6", "#FFE2EE", "#73DEFF", + ]), + + // sourced from https://www.flagcolorcodes.com/genderfaun + Self::Genderfaun => ColorProfile::from_hex_colors(vec![ + "#FCD689", "#FFF09B", "#FAF9CD", "#FFFFFF", "#8EDED9", "#8CACDE", "#9782EC", + ]), + + // sourced from https://www.flagcolorcodes.com/demifaun + Self::Demifaun => ColorProfile::from_hex_colors(vec![ + "#7F7F7F", "#C6C6C6", "#FCC688", "#FFF19C", "#FFFFFF", "#8DE0D5", "#9682EC", + "#C6C6C6", "#7F7F7F", + ]) + .and_then(|c| c.with_weights(vec![2, 2, 1, 1, 1, 1, 1, 2, 2])), + + // sourced from https://www.flagcolorcodes.com/genderfae + Self::Genderfae => ColorProfile::from_hex_colors(vec![ + "#97C3A5", "#C3DEAE", "#F9FACD", "#FFFFFF", "#FCA2C4", "#DB8AE4", "#A97EDD", + ]), + // used colorpicker to source form https://www.deviantart.com/pride-flags/art/Demifae-870194777 Self::Demifae => ColorProfile::from_hex_colors(vec![ "#7F7F7F", "#C5C5C5", "#97C3A4", "#C4DEAE", "#FFFFFF", "#FCA2C5", "#AB7EDF", @@ -199,55 +334,31 @@ impl Preset { ]) .and_then(|c| c.with_weights(vec![2, 2, 1, 1, 1, 1, 1, 2, 2])), - // sourced from https://www.flagcolorcodes.com/demifaun - Self::Demifaun => ColorProfile::from_hex_colors(vec![ - "#7F7F7F", "#C6C6C6", "#FCC688", "#FFF19C", "#FFFFFF", "#8DE0D5", "#9682EC", - "#C6C6C6", "#7F7F7F", + // sourced from https://www.flagcolorcodes.com/neutrois + Self::Neutrois => ColorProfile::from_hex_colors(vec!["#FFFFFF", "#1F9F00", "#000000"]), + + // sourced from https://www.flagcolorcodes.com/biromantic-alternate-2 + Self::Biromantic1 => ColorProfile::from_hex_colors(vec![ + "#8869A5", "#D8A7D8", "#FFFFFF", "#FDB18D", "#151638", + ]), + + // sourced from https://www.flagcolorcodes.com/autoromantic + Self::Autoromantic => ColorProfile::from_hex_colors( + // symbol interpreted + vec!["#99D9EA", "#3DA542", "#7F7F7F"], + ) + .and_then(|c| c.with_weights(vec![2, 1, 2])), + + // sourced from https://www.flagcolorcodes.com/boyflux-alternate-2 + Self::Boyflux2 => ColorProfile::from_hex_colors(vec![ + "#E48AE4", "#9A81B4", "#55BFAB", "#FFFFFF", "#A8A8A8", "#81D5EF", "#69ABE5", + "#5276D4", ]) - .and_then(|c| c.with_weights(vec![2, 2, 1, 1, 1, 1, 1, 2, 2])), + .and_then(|c| c.with_weights(vec![1, 1, 1, 1, 1, 5, 5, 5])), - // yellow sourced from https://lgbtqia.fandom.com/f/p/4400000000000041031 - // other colors sourced from demiboy and demigirl flags - Self::Demigender => ColorProfile::from_hex_colors(vec![ - "#7F7F7F", "#C4C4C4", "#FBFF75", "#FFFFFF", "#FBFF75", "#C4C4C4", "#7F7F7F", - ]), - - // sourced from https://www.flagcolorcodes.com/demigirl - Self::Demigirl => ColorProfile::from_hex_colors(vec![ - "#7F7F7F", "#C4C4C4", "#FDADC8", "#FFFFFF", "#FDADC8", "#C4C4C4", "#7F7F7F", - ]), - - Self::Femboy => ColorProfile::from_hex_colors(vec![ - "#d260a5", "#e4afcd", "#fefefe", "#57cef8", "#fefefe", "#e4afcd", "#d260a5", - ]), - - // sourced from https://lgbtqia.wiki/wiki/Finsexual - Self::Finsexual => ColorProfile::from_hex_colors(vec![ - "#B18EDF", "#D7B1E2", "#F7CDE9", "#F39FCE", "#EA7BB3", - ]), - - // sampled from https://es.m.wikipedia.org/wiki/Archivo:Fraysexual_flag.jpg - Self::Fraysexual => { - ColorProfile::from_hex_colors(vec!["#226CB5", "#94E7DD", "#FFFFFF", "#636363"]) - }, - - // sourced from https://www.flagcolorcodes.com/gay-men - Self::GayMen => ColorProfile::from_hex_colors(vec![ - "#078D70", "#98E8C1", "#FFFFFF", "#7BADE2", "#3D1A78", - ]), - - // sourced from https://www.flagcolorcodes.com/genderfae - Self::Genderfae => ColorProfile::from_hex_colors(vec![ - "#97C3A5", "#C3DEAE", "#F9FACD", "#FFFFFF", "#FCA2C4", "#DB8AE4", "#A97EDD", - ]), - - // sourced from https://www.flagcolorcodes.com/genderfaun - Self::Genderfaun => ColorProfile::from_hex_colors(vec![ - "#FCD689", "#FFF09B", "#FAF9CD", "#FFFFFF", "#8EDED9", "#8CACDE", "#9782EC", - ]), - - Self::Genderfluid => ColorProfile::from_hex_colors(vec![ - "#FE76A2", "#FFFFFF", "#BF12D7", "#000000", "#303CBE", + // sourced from https://commons.wikimedia.org/wiki/File:Girlflux_Pride_Flag.jpg + Self::Girlflux => ColorProfile::from_hex_colors(vec![ + "f9e6d7", "f2526c", "bf0311", "e9c587", "bf0311", "f2526c", "f9e6d7", ]), // sourced from https://www.deviantart.com/pride-flags/art/Genderflux-1-543925589 @@ -255,110 +366,9 @@ impl Preset { "f47694", "f2a2b9", "cecece", "7ce0f7", "3ecdf9", "fff48d", ]), - Self::GenderNonconforming1 => ColorProfile::from_hex_colors(vec![ - "#50284d", "#96467b", "#5c96f7", "#ffe6f7", "#5c96f7", "#96467b", "#50284d", - ]) - .and_then(|c| c.with_weights(vec![4, 1, 1, 1, 1, 1, 4])), - - Self::GenderNonconforming2 => ColorProfile::from_hex_colors(vec![ - "#50284d", "#96467b", "#5c96f7", "#ffe6f7", "#5c96f7", "#96467b", "#50284d", - ]), - - // sourced from: https://gender.fandom.com/wiki/Gendervoid - Self::Gendervoid => ColorProfile::from_hex_colors(vec![ - "#081149", "#4B484B", "#000000", "#4B484B", "#081149", - ]), - - // sourced from https://commons.wikimedia.org/wiki/File:Girlflux_Pride_Flag.jpg - Self::Girlflux => ColorProfile::from_hex_colors(vec![ - "f9e6d7", "f2526c", "bf0311", "e9c587", "bf0311", "f2526c", "f9e6d7", - ]), - - // sourced from https://www.flagcolorcodes.com/greygender - Self::Greygender => ColorProfile::from_hex_colors(vec![ - "#B3B3B3", "#FFFFFF", "#062383", "#FFFFFF", "#535353", - ]) - .and_then(|c| c.with_weights(vec![2, 1, 2, 1, 2])), - - // sourced from https://www.flagcolorcodes.com/greysexual - Self::Greysexual => ColorProfile::from_hex_colors(vec![ - "#740194", "#AEB1AA", "#FFFFFF", "#AEB1AA", "#740194", - ]), - - // sourced from https://lgbtqia.fandom.com/wiki/Gynesexual - Self::Gynesexual => { - ColorProfile::from_hex_colors(vec!["#F4A9B7", "#903F2B", "#5B953B"]) - }, - - // sourced from https://www.flagcolorcodes.com/intergender - Self::Intergender => { - ColorProfile::from_hex_colors(vec!["#900DC2", "#FFE54F", "#900DC2"]) - .and_then(|c| c.with_weights(vec![2, 1, 2])) - }, - - Self::Lesbian => ColorProfile::from_hex_colors(vec![ - "#D62800", "#FF9B56", "#FFFFFF", "#D462A6", "#A40062", - ]), - - // sourced from https://www.flagcolorcodes.com/neutrois - Self::Neutrois => ColorProfile::from_hex_colors(vec!["#FFFFFF", "#1F9F00", "#000000"]), - - Self::Nonbinary => { - ColorProfile::from_hex_colors(vec!["#FCF431", "#FCFCFC", "#9D59D2", "#282828"]) - }, - - // used https://twitter.com/foxbrained/status/1667621855518236674/photo/1 as source and colorpicked - Self::NonhumanUnity => { - ColorProfile::from_hex_colors(vec!["#177B49", "#FFFFFF", "#593C90"]) - }, - - Self::Omniromantic => ColorProfile::from_hex_colors(vec![ - "#FEC8E4", "#FDA1DB", "#89739A", "#ABA7FE", "#BFCEFF", - ]), - - // sourced from https://www.flagcolorcodes.com/omnisexual - Self::Omnisexual => ColorProfile::from_hex_colors(vec![ - "#FE9ACE", "#FF53BF", "#200044", "#6760FE", "#8EA6FF", - ]), - - Self::Pangender => ColorProfile::from_hex_colors(vec![ - "#FFF798", "#FEDDCD", "#FFEBFB", "#FFFFFF", "#FFEBFB", "#FEDDCD", "#FFF798", - ]), - - Self::Pansexual => ColorProfile::from_hex_colors(vec!["#FF1C8D", "#FFD700", "#1AB3FF"]), - - // used https://pluralpedia.org/w/Plurality#/media/File:Plural-Flag-1.jpg as source and colorpicked - Self::Plural => ColorProfile::from_hex_colors(vec![ - "#2D0625", "#543475", "#7675C3", "#89C7B0", "#F3EDBD", - ]), - - Self::Polysexual => { - ColorProfile::from_hex_colors(vec!["#F714BA", "#01D66A", "#1594F6"]) - }, - - Self::Queer => ColorProfile::from_hex_colors(vec!["#B57FDD", "#FFFFFF", "#49821E"]), - - Self::Rainbow => ColorProfile::from_hex_colors(vec![ - "#E50000", "#FF8D00", "#FFEE00", "#028121", "#004CFF", "#770088", - ]), - - Self::Tomboy => ColorProfile::from_hex_colors(vec![ - "#2f3fb9", "#613a03", "#fefefe", "#f1a9b7", "#fefefe", "#613a03", "#2f3fb9", - ]), - - // used colorpicker to source from https://www.deviantart.com/pride-flags/art/Trans-Woman-Transfeminine-1-543925985 - // linked from https://gender.fandom.com/wiki/Transfeminine - Self::Transfeminine => ColorProfile::from_hex_colors(vec![ - "#73DEFF", "#FFE2EE", "#FFB5D6", "#FF8DC0", "#FFB5D6", "#FFE2EE", "#73DEFF", - ]), - - Self::Transgender => ColorProfile::from_hex_colors(vec![ - "#55CDFD", "#F6AAB7", "#FFFFFF", "#F6AAB7", "#55CDFD", - ]), - - // sourced from https://www.flagcolorcodes.com/transmasculine - Self::Transmasculine => ColorProfile::from_hex_colors(vec![ - "#FF8ABD", "#CDF5FE", "#9AEBFF", "#74DFFF", "#9AEBFF", "#CDF5FE", "#FF8ABD", + // sourced from https://lgbtqia.wiki/wiki/Finsexual + Self::Finsexual => ColorProfile::from_hex_colors(vec![ + "#B18EDF", "#D7B1E2", "#F7CDE9", "#F39FCE", "#EA7BB3", ]), // sourced from https://web.archive.org/web/20221002181913/https://unlabeledinfo.carrd.co/#flags @@ -371,18 +381,79 @@ impl Preset { "#250548", "#FFFFFF", "#F7DCDA", "#EC9BEE", "#9541FA", "#7D2557", ]), + Self::Pangender => ColorProfile::from_hex_colors(vec![ + "#FFF798", "#FEDDCD", "#FFEBFB", "#FFFFFF", "#FFEBFB", "#FEDDCD", "#FFF798", + ]), + + Self::GenderNonconforming1 => ColorProfile::from_hex_colors(vec![ + "#50284d", "#96467b", "#5c96f7", "#ffe6f7", "#5c96f7", "#96467b", "#50284d", + ]) + .and_then(|c| c.with_weights(vec![4, 1, 1, 1, 1, 1, 4])), + + Self::GenderNonconforming2 => ColorProfile::from_hex_colors(vec![ + "#50284d", "#96467b", "#5c96f7", "#ffe6f7", "#5c96f7", "#96467b", "#50284d", + ]), + + Self::Femboy => ColorProfile::from_hex_colors(vec![ + "#d260a5", "#e4afcd", "#fefefe", "#57cef8", "#fefefe", "#e4afcd", "#d260a5", + ]), + + Self::Tomboy => ColorProfile::from_hex_colors(vec![ + "#2f3fb9", "#613a03", "#fefefe", "#f1a9b7", "#fefefe", "#613a03", "#2f3fb9", + ]), + + // sourced from https://lgbtqia.fandom.com/wiki/Gynesexual + Self::Gynesexual => { + ColorProfile::from_hex_colors(vec!["#F4A9B7", "#903F2B", "#5B953B"]) + }, + + // sourced from https://lgbtqia.fandom.com/wiki/Androsexual + Self::Androsexual => { + ColorProfile::from_hex_colors(vec!["#01CCFF", "#603524", "#B799DE"]) + }, + // sourced from: https://gender.fandom.com/wiki/Gendervoid - Self::Voidboy => ColorProfile::from_hex_colors(vec![ - "#0B130C", "#547655", "#66B969", "#547655", "#0B130C", + Self::Gendervoid => ColorProfile::from_hex_colors(vec![ + "#081149", "#4B484B", "#000000", "#4B484B", "#081149", ]), // sourced from: https://gender.fandom.com/wiki/Gendervoid Self::Voidgirl => ColorProfile::from_hex_colors(vec![ "#180827", "#7A5A8B", "#E09BED", "#7A5A8B", "#180827", ]), - // sourced from https://commons.wikimedia.org/wiki/File:Xenogender_pride_flag.svg - Self::Xenogender => ColorProfile::from_hex_colors(vec![ - "#FF6692", "#FF9A98", "#FFB883", "#FBFFA8", "#85BCFF", "#9D85FF", "#A510FF", + + // sourced from: https://gender.fandom.com/wiki/Gendervoid + Self::Voidboy => ColorProfile::from_hex_colors(vec![ + "#0B130C", "#547655", "#66B969", "#547655", "#0B130C", + ]), + + // used https://twitter.com/foxbrained/status/1667621855518236674/photo/1 as source and colorpicked + Self::NonhumanUnity => { + ColorProfile::from_hex_colors(vec!["#177B49", "#FFFFFF", "#593C90"]) + }, + + // used https://pluralpedia.org/w/Plurality#/media/File:Plural-Flag-1.jpg as source and colorpicked + Self::Plural => ColorProfile::from_hex_colors(vec![ + "#2D0625", "#543475", "#7675C3", "#89C7B0", "#F3EDBD", + ]), + + // sampled from https://es.m.wikipedia.org/wiki/Archivo:Fraysexual_flag.jpg + Self::Fraysexual => { + ColorProfile::from_hex_colors(vec!["#226CB5", "#94E7DD", "#FFFFFF", "#636363"]) + }, + + Self::Beiyang => ColorProfile::from_hex_colors(vec![ + "#DF1B12", "#FFC600", "#01639D", "#FFFFFF", "#000000", + ]), + + Self::Burger => ColorProfile::from_hex_colors(vec![ + "#F3A26A", "#498701", "#FD1C13", "#7D3829", "#F3A26A", + ]), + + // used https://gilbertbaker.com/rainbow-flag-color-meanings/ as source and colorpicked + Self::Baker => ColorProfile::from_hex_colors(vec![ + "#F23D9E", "#F80A24", "#F78022", "#F9E81F", "#1E972E", "#1B86BC", "#243897", + "#6F0A82", ]), }) .expect("preset color profiles should not be invalid") @@ -516,11 +587,10 @@ impl ColorProfile { self.colors.iter().map(|c| c.into_linear()).collect(); { - let hsl_f32_colors: &mut [Hsl>] = - &mut rgb_f32_colors.into_color_mut(); + let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut(); - for hsl_f32_color in hsl_f32_colors { - hsl_f32_color.lightness *= multiplier; + for okhsl_f32_color in okhsl_f32_colors { + okhsl_f32_color.lightness *= multiplier; } } @@ -534,25 +604,25 @@ impl ColorProfile { } } - /// Creates a new color profile, with the colors set to the specified HSL - /// lightness value. + /// Creates a new color profile, with the colors set to the specified + /// [`Okhsl`] lightness value. pub fn with_lightness(&self, assign_lightness: AssignLightness) -> Self { let mut rgb_f32_colors: Vec<_> = self.colors.iter().map(|c| c.into_format::()).collect(); { - let hsl_f32_colors: &mut [Hsl] = &mut rgb_f32_colors.into_color_mut(); + let okhsl_f32_colors: &mut [Okhsl] = &mut rgb_f32_colors.into_color_mut(); - for hsl_f32_color in hsl_f32_colors { + for okhsl_f32_color in okhsl_f32_colors { match assign_lightness { AssignLightness::Replace(lightness) => { - hsl_f32_color.lightness = lightness.into(); + okhsl_f32_color.lightness = lightness.into(); }, AssignLightness::ClampMax(lightness) => { - hsl_f32_color.lightness.clamp_max_assign(lightness.into()); + okhsl_f32_color.lightness.clamp_max_assign(lightness.into()); }, AssignLightness::ClampMin(lightness) => { - hsl_f32_color.lightness.clamp_min_assign(lightness.into()); + okhsl_f32_color.lightness.clamp_min_assign(lightness.into()); }, } } @@ -568,8 +638,8 @@ impl ColorProfile { } } - /// Creates a new color profile, with the colors set to the specified HSL - /// lightness value, with respect to dark/light terminals. + /// Creates a new color profile, with the colors set to the specified + /// [`Okhsl`] lightness value, with respect to dark/light terminals. pub fn with_lightness_dl( &self, lightness: Lightness, diff --git a/crates/hyfetch/src/types.rs b/crates/hyfetch/src/types.rs index 7143d05f..b2ead9b9 100644 --- a/crates/hyfetch/src/types.rs +++ b/crates/hyfetch/src/types.rs @@ -1,20 +1,28 @@ use serde::{Deserialize, Serialize}; -use strum::{EnumString, VariantNames}; +use strum::{EnumString, IntoStaticStr, VariantNames}; #[derive( - Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize, EnumString, Serialize, VariantNames, + Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize, EnumString, IntoStaticStr, Serialize, )] #[serde(rename_all = "lowercase")] #[strum(serialize_all = "lowercase")] pub enum AnsiMode { + #[serde(rename = "ansi")] + #[serde(skip)] + #[strum(serialize = "ansi")] + #[strum(disabled)] + Ansi16, #[serde(rename = "8bit")] #[strum(serialize = "8bit")] Ansi256, Rgb, } -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize, Serialize)] +#[derive( + Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize, EnumString, IntoStaticStr, Serialize, +)] #[serde(rename_all = "lowercase")] +#[strum(serialize_all = "lowercase")] pub enum LightDark { Light, Dark, @@ -31,3 +39,8 @@ pub enum Backend { Fastfetch, FastfetchOld, } + +// See https://github.com/Peternator7/strum/issues/244 +impl VariantNames for AnsiMode { + const VARIANTS: &'static [&'static str] = &["8bit", "rgb"]; +}