From 9c9287c5ff3e70f917195c5f93920d7fc53add35 Mon Sep 17 00:00:00 2001 From: Virt <41426325+VirtCode@users.noreply.github.com> Date: Wed, 16 Jul 2025 03:07:23 +0200 Subject: [PATCH] feat: discord rpc setting is working, just updates are left --- .gitignore | 1 + Cargo.lock | 828 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 7 + assets/LICENSE | 23 ++ assets/languages.json | 410 +++++++++++++++++++++ rustfmt.toml | 4 + src/discord.rs | 97 +++++ src/language.rs | 50 +++ src/main.rs | 63 +++- 9 files changed, 1481 insertions(+), 2 deletions(-) create mode 100644 Cargo.lock create mode 100644 assets/LICENSE create mode 100644 assets/languages.json create mode 100644 rustfmt.toml create mode 100644 src/discord.rs create mode 100644 src/language.rs diff --git a/.gitignore b/.gitignore index ea8c4bf..21f0afc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +.zed diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..f57de8a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,828 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "serde", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.59.0", +] + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "discord-rich-presence" +version = "0.2.5" +source = "git+https://github.com/vionya/discord-rich-presence#9c6cabe04a70cfcc822affd1bf8be51321f8a821" +dependencies = [ + "log", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "thiserror", + "uuid", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-lite" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "hl-zed-dc-rpc" +version = "0.1.0" +dependencies = [ + "anyhow", + "discord-rich-presence", + "env_logger", + "hyprland", + "log", + "regex", + "serde_json", +] + +[[package]] +name = "hyprland" +version = "0.4.0-beta.2" +source = "git+https://github.com/hyprland-community/hyprland-rs#fce63060619422f52563514b474398e380e5fc51" +dependencies = [ + "ahash", + "async-stream", + "derive_more", + "either", + "futures-lite", + "hyprland-macros", + "num-traits", + "once_cell", + "paste", + "phf", + "serde", + "serde_json", + "serde_repr", + "tokio", +] + +[[package]] +name = "hyprland-macros" +version = "0.4.0-beta.2" +source = "git+https://github.com/hyprland-community/hyprland-rs#fce63060619422f52563514b474398e380e5fc51" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "io-uring" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.59.0", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "slab" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio" +version = "1.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "slab", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index a756a09..26da3f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,10 @@ version = "0.1.0" edition = "2024" [dependencies] +anyhow = "1.0.98" +discord-rich-presence = { git = "https://github.com/vionya/discord-rich-presence" } # git cause errors +env_logger = "0.11.8" +hyprland = { git = "https://github.com/hyprland-community/hyprland-rs" } +log = "0.4.27" +regex = "1.11.1" +serde_json = "1.0.140" diff --git a/assets/LICENSE b/assets/LICENSE new file mode 100644 index 0000000..a713e68 --- /dev/null +++ b/assets/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2020-2022 iCrawl +Copyright (c) 2020-2022 Satoqz +Copyright (c) 2020-2023 Narcis B. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/assets/languages.json b/assets/languages.json new file mode 100644 index 0000000..de9fa3b --- /dev/null +++ b/assets/languages.json @@ -0,0 +1,410 @@ +{ + "nodemon.json": "nodemon", + "package.json": "npm", + "turbo.json": "turbo", + "regex:(vercel|now)\\.json": "vercel", + "regex:\\.prettier((rc)|(\\.(toml|yml|yaml|json|js))?)$": "prettier", + "regex:\\.eslint((rc|ignore)|(\\.(json|js))?)$": "eslint", + "regex:\\.(now|vercel)ignore$": "vercel", + "regex:prettier\\.config\\.js$": "prettier", + "regex:vue\\.config\\.(js|ts)$": "vueconfig", + "regex:vite\\.config\\.(js|ts)$": "viteconfig", + "regex:vitest\\.config\\.(js|ts|mjs)$": "vitestconfig", + "regex:jest\\.config\\.(js|ts)$": "jest", + "regex:tailwind\\.config\\.(js|cjs|mjs|ts|cts|mts)$": "tailwind", + "regex:gatsby-(browser|node|ssr|config)\\.js$": "gatsbyjs", + "regex:webpack(\\.dev|\\.development|\\.prod|\\.production)?\\.config(\\.babel)?\\.(js|jsx|coffee|ts|json|json5|yaml|yml)$": "webpack", + "babel.config.js": "babel", + ".ahk": "ahk", + ".ahkl": "ahk", + ".astro": "astro", + ".astro.config.mjs": "astroconfig", + "androidmanifest.xml": "android", + ".bp": "android", + "regex:^angular[^.]*\\.js$": "angular", + ".ng": "angular", + ".applescript": "applescript", + "regex:(\\.)?appveyor\\.yml$": "appveyor", + ".ino": "arduino", + ".swf": "as", + ".as": "as", + ".jsfl": "as", + ".swc": "as", + ".asp": "asp", + ".asax": "asp", + ".ascx": "asp", + ".ashx": "asp", + ".asmx": "asp", + ".aspx": "asp", + ".axd": "asp", + "regex:\\.(l?a|[ls]?o|out|s|a51|asm|axf|elf|prx|puff|z80)$": "assembly", + ".agc": "assembly", + ".ko": "assembly", + ".kv": "kivy", + ".ks": "kag-script", + ".tjs": "kirikiri-tpv-javascript", + ".lst": "assembly", + "regex:\\.((c([+px]{2}?)?-?)?objdump|bsdiff|bin|dat|pak|pdb)$": "assembly", + ".d-objdump": "assembly", + "regex:\\.gcode|\\.gco$": "assembly", + "regex:\\.rpy[bc]$": "assembly", + "regex:\\.py[co]$": "assembly", + ".swp": "assembly", + ".DS_Store": "assembly", + ".au3": "autoit", + "regex:\\.babelrc$": "babel", + ".bat": "bat", + ".batch": "bat", + ".cmd": "bat", + "regex:\\.(exe|com|msi)$": "bat", + ".reg": "bat", + "regex:^(BUILD|WORKSPACE|\\.bzl|\\.bazel(rc)?|\\.s(tar|ky))$": "bazel", + "regex:^(\\.bowerrc|bower\\.json|Bowerfile)$": "bower", + "regex:\\.bf?$": "brainfuck", + "regex:\\.c$": "c", + "regex:(cargo\\.toml|cargo\\.lock)$": "cargo", + ".casc": "casc", + ".cas": "casc", + ".ces": "citrinescript", + ".cfc": "coldfusion", + ".cfm": "coldfusion", + "circle.yml": "circleci", + ".clj": "clojure", + ".cl2": "clojure", + ".cljc": "clojure", + ".cljx": "clojure", + ".hic": "clojure", + "regex:\\.cljs(cm)?$": "clojure", + ".cmake": "cmake", + "regex:^CMakeLists\\.txt$": "cmake", + "regex:\\.codeclimate\\.(yml|json)$": "codeclimate", + ".cbl": "cobol", + ".cob": "cobol", + ".coffee": "coffee", + ".cjsx": "coffee", + ".coffee.ecr": "coffee", + "regex:contenthook\\.config\\.(ts|cjs|mjs|js)$": "contenthook", + ".coffee.erb": "coffee", + ".litcoffee": "coffee", + ".iced": "coffee", + ".cos": "cosmo", + ".⭐": "cosmo", + "regex:\\.c[+px]{2}$|\\.cc$": "cpp", + "regex:\\.h[+px]{2}$": "cpp", + "regex:\\.[it]pp$": "cpp", + "regex:\\.(tcc|inl)$": "cpp", + ".cats": "cpp", + ".idc": "cpp", + ".w": "cpp", + ".nc": "cpp", + ".upc": "cpp", + ".xpm": "cpp", + "regex:\\.e?cr$": "crystal", + ".cs": "csharp", + ".csx": "csharp", + ".cshtml": "razor", + ".csproj": "csproj", + ".css": "css", + ".css.map": "cssmap", + ".cu": "cuda", + ".pyx": "cython", + "regex:\\.di?$": "d", + ".dart": "dart", + ".dfm": "delphi", + ".dpr": "delphi", + ".dsc": "denizen", + ".dm": "dm", + ".dme": "dm", + ".dmm": "dm", + "regex:^(Dockerfile|docker-compose|\\.docker(file|ignore))$": "docker", + "regex:^docker-sync\\.yml$": "docker", + ".edge": "edge", + ".editorconfig": "editorconfig", + ".ejs": "ejs", + ".ex": "elixir", + "regex:\\.(exs|l?eex)$": "elixir", + "regex:^mix\\.(exs?|lock)$": "elixir", + ".elm": "elm", + ".env": "env", + ".erl": "erlang", + "regex:\\.([fF])(03|08|18|90|95)$": "fortran", + ".beam": "erlang", + ".hrl": "erlang", + ".xrl": "erlang", + ".yrl": "erlang", + ".app.src": "erlang", + "regex:^Emakefile$": "erlang", + "regex:^rebar(\\.config)?\\.lock$": "erlang", + "regex:(\\.firebaserc|firebase\\.json)$": "firebase", + ".flowconfig": "flowconfig", + ".fs": "fsharp", + ".fsi": "fsharp", + ".fsscript": "fsharp", + ".fsx": "fsharp", + "regex:^Gemfile(\\.lock)?$": "gemfile", + "regex:^\\.git|^\\.keep$|\\.mailmap$": "git", + ".gml": "gml", + ".gleam": "gleam", + ".go": "go", + ".gd": "godot", + ".gr": "grain", + ".gradle": "gradle", + "gradlew": "gradle", + "regex:\\.(g|c)sc$": "gamescript", + ".gql": "graphql", + ".graphql": "graphql", + ".groovy": "groovy", + "regex:\\.gv?y$": "groovy", + ".gsh": "groovy", + "regex:[Gg]runtfile\\.(js|coffee)$": "gruntfile", + "gulpfile.js": "gulp", + "regex:\\.(hbs|handlebars|(mu)?stache)$": "handlebars", + ".prg": "harbour", + ".ha": "hare", + ".hbp": "harbour", + ".hbc": "harbour", + ".rc": "harbour", + ".fmg": "harbour", + ".hs": "haskell", + ".hsc": "haskell", + ".c2hs": "haskell", + ".c3": "c3", + ".lhs": "haskell", + "regex:\\.(hlsl|cginc|cg|shader|fx)$": "hlsl", + "regex:\\.(glsl|vert|frag|geom|tesc|tese|comp)$": "glsl", + "regex:\\.hx(ml)?$": "haxe", + "^procfile$": "heroku", + ".heex": "heex", + "heroku.yml": "heroku", + ".hjson": "hjson", + ".hc": "holyc", + "regex:\\.x?html?$": "html", + ".http": "http", + ".rest": "http", + ".jar": "jar", + ".java": "java", + ".j2": "jinja", + ".jinja": "jinja", + ".js": "JavaScript", + ".es6": "JavaScript", + ".es": "JavaScript", + ".mjs": "JavaScript", + ".js.map": "jsmap", + ".json": "json", + ".jsonc": "json", + ".jsx": "jsx", + ".jule": "jule", + "regex:\\.(jil|jl)$": "julia", + ".ipynb": "jupyter", + "regex:\\.kt[ms]?$": "kotlin", + ".less": "less", + "regex:\\.l(i?sp)?$": "lisp", + "regex:\\.n[ly]$": "lisp", + ".podsl": "lisp", + "regex:\\.s([s]|(cm)|(exp))$": "lisp", + ".ls": "livescript", + ".log": "log", + "regex:\\.([w]|(pd_))?lua$": "lua", + "regex:\\.luau$": "luau", + "regex:\\.rbx(?:lx|l|m|s)?$": "luau", + "^Makefile$": "makefile", + "^mk\\.config$": "makefile", + "regex:\\.(mk|mak|make)$": "makefile", + "regex:^BSDmakefile$": "makefile", + "regex:^GNUmakefile$": "makefile", + "regex:^makefile\\.sco$": "makefile", + "regex:^Kbuild$": "makefile", + "regex:^makefile$": "makefile", + "regex:^mkfile$": "makefile", + "regex:^\\.?qmake$": "makefile", + "regex:\\.(geo|topo)$": "manifest", + ".cson": "manifest", + ".json5": "manifest", + ".ndjson": "manifest", + ".fea": "manifest", + ".json.eex": "manifest", + ".pawn": "pawn", + ".proto": "manifest", + ".pytb": "manifest", + ".pydeps": "manifest", + "regex:\\.pot?$": "manifest", + ".ejson": "manifest", + ".edn": "manifest", + ".eam.fs": "manifest", + ".qml": "manifest", + ".qbs": "manifest", + ".ston": "manifest", + ".ttl": "manifest", + ".rviz": "manifest", + ".sol": "solidity", + ".syntax": "manifest", + ".webmanifest": "manifest", + "regex:^pkginfo$": "manifest", + ".moon": "moonscript", + "regex:^mime\\.types$": "manifest", + "regex:^METADATA\\.pb$": "manifest", + "regex:/\\\\[/\\\\][-.\\w]+$": "manifest", + "lib/icons/.icondb.js": "manifest", + "regex:\\.git/\\\\?(HEAD|ORIG_HEAD|packed-refs|logs/\\\\?[^/\\\\]+)$": "manifest", + "regex:\\.(md|mdown|markdown|mkd|mkdown|mdwn|mkdn|rmd|ron|pmd)$": "markdown", + ".mdx": "markdownx", + ".marko": "marko", + "regex:\\.m$": "matlab", + ".nim": "nim", + ".nims": "nim", + ".nimble": "nim", + ".nix": "nix", + ".npmrc": "npm", + ".npmignore": "npm", + ".nut": "squirrel", + "regex:\\.mm?$": "objective-c", + ".pch": "objective-c", + ".x": "objective-c", + "regex:\\.eliom[i]?$": "ocaml", + "regex:\\.ml[4lyi]?$": "ocaml", + ".mt": "metal", + ".odin": "odin", + ".onyx": "onyx", + "regex:\\.pas(cal)?$": "pascal", + ".lpr": "pascal", + ".inc": "pawn", + ".sma": "pawn", + "regex:\\.p(wn)?$": "pawn", + ".sp": "sourcepawn", + "regex:\\.p(er)?l$": "perl", + ".al": "perl", + "regex:\\.p([hm]|lx)$": "perl", + "regex:\\.(psgi|xs)$": "perl", + ".pl6": "perl", + "regex:\\.[tp]6$|\\.6pl$": "perl", + "regex:\\.(pm6|p6m)$": "perl", + ".6pm": "perl", + ".nqp": "perl", + ".p6l": "perl", + ".pod6": "perl", + "regex:^Rexfile$": "perl", + "regex:\\.php([st\\d]|_cs)?$": "php", + "^Phakefile$": "php", + ".pony": "ponylang", + ".pcss": "postcss", + "regex:\\.ps[md]?1$": "powershell", + ".ps1xml": "powershell", + ".prettierignore": "prettier", + "prisma.yml": "prisma", + ".pde": "processing", + ".jade": "pug", + ".pug": "pug", + ".purs": "purescript", + ".ipy": "python", + ".isolate": "python", + ".pep": "python", + "regex:\\.gypi?$": "python", + ".pyde": "python", + "regex:\\.py([wi3tp]|de)?$": "python", + ".tac": "python", + ".wsgi": "python", + ".xpy": "python", + ".rpy": "python", + "regex:\\.?(pypirc|pythonrc|python-venv)$": "python", + "regex:^(SConstruct|SConscript)$": "python", + "regex:^(Snakefile|WATCHLISTS)$": "python", + "regex:^wscript$": "python", + "regex:\\.(r|Rprofile|rsx|rd)$": "r", + ".razor": "razor", + "regex:\\.res?i?$": "reasonml", + ".rst": "restructuredtext", + "regex:\\.(rb|ru|ruby|erb|gemspec|god|mspec|pluginspec|podspec|rabl|rake|opal)$": "ruby", + "regex:^\\.?(irbrc|gemrc|pryrc|ruby-(gemset|version))$": "ruby", + "regex:^(Appraisals|(Rake|[bB]uild|Cap|Danger|Deliver|Fast|Guard|Jar|Maven|Pod|Puppet|Snap)file(\\.lock)?)$": "ruby", + "regex:\\.(jbuilder|rbuild|rb[wx]|builder)$": "ruby", + "regex:^rails$": "ruby", + ".watchr": "ruby", + ".rs": "rust", + "regex:\\.(sc|scala)$": "scala", + "regex:\\.s[ac]ss$": "scss", + "regex:\\.(sh|rc|bats|bash|tool|install|command)$": "shell", + "regex:^(\\.?bash(rc|[-_]?(profile|login|logout|history|prompt))|_osc|config|install-sh|PKGBUILD)$": "shell", + "regex:\\.(ksh|mksh|pdksh)$": "shell", + ".sh-session": "shell", + "regex:\\.zsh(-theme|_history)?$|^\\.?(antigen|zpreztorc|zlogin|zlogout|zprofile|zshenv|zshrc)$": "shell", + "regex:\\.fish$|^\\.fishrc$": "shell", + "regex:^\\.?(login|profile)$": "shell", + ".inputrc": "shell", + ".tmux": "shell", + "regex:^(configure|config\\.(guess|rpath|status|sub)|depcomp|libtool|compile)$": "shell", + "regex:^/(private/)?etc/([^/]+/)*(profile$|nanorc$|rc\\.|csh\\.)$": "shell", + "regex:^\\.?cshrc$": "shell", + ".profile": "shell", + ".tcsh": "shell", + ".csh": "shell", + ".sk": "skript", + ".sqf": "sqf", + "regex:\\.(my)?sql$": "sql", + ".ddl": "sql", + ".udf": "sql", + ".hql": "sql", + ".rkt": "racket", + ".viw": "sql", + ".prc": "sql", + ".cql": "sql", + ".db2": "sql", + "regex:\\.(styl|stylus)$": "stylus", + ".sln": "csproj", + "regex:\\.sv(h)?$": "systemverilog", + ".svelte": "svelte", + ".svg": "svg", + ".swift": "swift", + "regex:\\.tex(i)?$": "tex", + ".ltx": "tex", + ".aux": "tex", + ".sty": "tex", + ".dtx": "tex", + ".cls": "tex", + ".ins": "tex", + ".lbx": "tex", + ".mkiv": "tex", + "regex:\\.mk[vi]i$": "tex", + "regex:^hyphen(ex)?\\.(cs|den|det|fr|sv|us)$": "tex", + "regex:\\.te?xt$": "text", + ".rtf": "text", + "regex:\\.i?nfo$": "text", + ".msg": "text", + "regex:\\.(utxt|utf8)$": "text", + ".toml": "toml", + ".travis.yml": "travis", + ".ts.map": "tsmap", + "regex:.*\\.d\\.ts$": "typescript-def", + ".ts": "TypeScript", + ".tsx": "tsx", + ".twig": "twig", + ".umm": "umm", + ".v": "v", + ".vh": "v", + ".vala": "vala", + ".vapi": "vala", + ".vb": "vb", + ".vbs": "vb", + ".vbhtml": "vb", + ".vbproj": "vb", + ".vba": "vba", + ".vcxproj": "vcxproj", + ".verse": "verse", + ".vscodeignore": "vscodeignore", + ".vue": "vue", + ".zu": "zura", + ".zura": "zura", + ".wat": "wasm", + ".wast": "wasm", + ".wasm": "wasm", + ".xml": "xml", + ".xaml": "xaml", + "regex:\\.ya?ml$": "yaml", + "regex:^yarn(\\.lock)?$": "yarn", + ".yarnrc": "yarn", + ".zig": "zig", + ".maeel": "maeel", + "regex:\\.(tfvars|tf)$": "terraform", + "regex:\\.mojo$": "mojo", + ".🔥": "mojo", + ".zs": "zs" +} diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..f1dd728 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +max_width = 100 +use_small_heuristics = "Max" + +wrap_comments = true diff --git a/src/discord.rs b/src/discord.rs new file mode 100644 index 0000000..174dc0a --- /dev/null +++ b/src/discord.rs @@ -0,0 +1,97 @@ +/* + * This file WAS ONCE is part of discord-presence. Extension for Zed that adds support for Discord Rich Presence using LSP. It is heavily modified to be used here. + * + * Copyright (c) 2025 Steinhübl, Virt + */ + +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +use anyhow::{Context, Result}; +use discord_rich_presence::{ + DiscordIpc, DiscordIpcClient, + activity::{Activity, Assets, Button, Timestamps}, +}; +use log::{debug, error, info}; + +#[derive(Debug)] +pub struct Discord { + client: DiscordIpcClient, + start_timestamp: Duration, +} + +impl Discord { + pub fn new(id: &str) -> Result { + let since_epoch = + SystemTime::now().duration_since(UNIX_EPOCH).expect("we are after 1970 right??"); + + Ok(Self { client: DiscordIpcClient::new(id), start_timestamp: since_epoch }) + } + + pub fn connect(&mut self) -> Result<()> { + debug!("connecting to discord"); + + self.client.connect().context("failed to connect to discord ipc")?; + + info!("successfully connected to discord"); + Ok(()) + } + + pub fn disconnect(&mut self) -> Result<()> { + debug!("disconnecting from discord"); + + self.client.close().context("failed to disconnect from discord") + } + + pub fn clear(&mut self) -> Result<()> { + debug!("clearing discord activity"); + + self.client.clear_activity().context("failed to clear activity") + } + + #[allow(clippy::too_many_arguments)] + pub fn set( + &mut self, + state: Option, + details: Option, + large_image: Option, + large_text: Option, + small_image: Option, + small_text: Option, + git_remote_url: Option, + ) -> Result<()> { + let activity = Activity::new() + .timestamps(Timestamps::new().start(self.start_timestamp.as_millis() as i64)) + .buttons( + git_remote_url + .as_ref() + .map(|url| vec![Button::new("View Repository", url)]) + .unwrap_or_default(), + ); + + let activity = set_optional_field(activity, state.as_deref(), Activity::state); + let activity = set_optional_field(activity, details.as_deref(), Activity::details); + + let assets = Assets::new(); + let assets = set_optional_field(assets, large_image.as_deref(), Assets::large_image); + let assets = set_optional_field(assets, large_text.as_deref(), Assets::large_text); + let assets = set_optional_field(assets, small_image.as_deref(), Assets::small_image); + let assets = set_optional_field(assets, small_text.as_deref(), Assets::small_text); + + let activity = activity.assets(assets); + + self.client.set_activity(activity).context("failed to update discord activity")?; + + debug!("updated discord activity"); + Ok(()) + } +} + +pub fn set_optional_field<'a, T, F>(mut obj: T, field: Option<&'a str>, setter: F) -> T +where + F: FnOnce(T, &'a str) -> T, +{ + if let Some(value) = field { + obj = setter(obj, value); + } + obj +} diff --git a/src/language.rs b/src/language.rs new file mode 100644 index 0000000..ae3a200 --- /dev/null +++ b/src/language.rs @@ -0,0 +1,50 @@ +use std::{collections::HashMap, sync::LazyLock}; + +use regex::{Regex, RegexBuilder}; + +static LANGUAGES: LazyLock> = LazyLock::new(|| { + let map: HashMap = + serde_json::from_str(include_str!("../assets/languages.json")) + .expect("failed to deserialize language map"); + + map.into_iter().map(|(qualifier, lang)| (LanguageQualifier::create(qualifier), lang)).collect() +}); + +pub enum LanguageQualifier { + Name(String), + Ending(String), + Regex(Regex), +} + +impl LanguageQualifier { + pub fn create(input: String) -> Self { + if let Some(input) = input.strip_prefix("regex:") { + Self::Regex( + RegexBuilder::new(input) + .case_insensitive(true) + .build() + .expect("could not compile regex in languages map"), + ) + } else if input.starts_with('.') { + Self::Ending(input) + } else { + Self::Name(input) + } + } + + pub fn matches(&self, filename: &str) -> bool { + match self { + LanguageQualifier::Name(name) => filename == name, + LanguageQualifier::Ending(ending) => filename.ends_with(ending), + LanguageQualifier::Regex(regex) => regex.is_match(filename), + } + } +} + +pub fn get_language(filename: &str) -> String { + LANGUAGES + .iter() + .find(|(quali, _)| quali.matches(filename)) + .map(|(_, lang)| lang.clone()) + .unwrap_or_else(|| "text".to_string()) +} diff --git a/src/main.rs b/src/main.rs index e7a11a9..2ef9155 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,62 @@ -fn main() { - println!("Hello, world!"); +use std::{thread::sleep, time::Duration}; + +use anyhow::Result; +use discord::Discord; +use hyprland::{ + data::{Client, Clients}, + event_listener::EventListener, + shared::HyprData, +}; +use language::get_language; + +pub mod discord; +pub mod language; + +const APP_ID: &str = "1263505205522337886"; +const ICONS_URL: &str = + "https://raw.githubusercontent.com/xhyrom/zed-discord-presence/main/assets/icons"; + +fn main() -> Result<()> { + let mut discord = Discord::new(APP_ID)?; + discord.connect()?; + + update_discord(&mut discord)?; + //set_activity(&mut discord, "main.rs", "a secret new rust project")?; + + sleep(Duration::from_secs(10)); + + Ok(()) +} + +pub fn update_discord(discord: &mut Discord) -> Result<()> { + let mut clients = + Clients::get()?.into_iter().filter(|c| c.class == "dev.zed.Zed").collect::>(); + clients.sort_by(|c, d| c.focus_history_id.cmp(&d.focus_history_id)); + + if let Some(client) = clients.first() { + let split = client.title.split('—').collect::>(); + + if split.len() == 1 { + set_activity(discord, "not-doing-anything-atm", split[0].trim())?; + } else if split.len() == 2 { + set_activity(discord, split[1].trim(), split[0].trim())?; + } + } + + Ok(()) +} + +pub fn set_activity(discord: &mut Discord, file: &str, workspace: &str) -> Result<()> { + let language = get_language(file); + let language_upper: String = language.chars().take(1).chain(language.chars().skip(1)).collect(); + + discord.set( + Some(format!("Editing {file}")), + Some(format!("In {workspace}")), + Some(format!("{ICONS_URL}/{language}.png")), + Some(language_upper), + Some(format!("{ICONS_URL}/zed.png")), + Some("Zed".to_string()), + None, + ) }