From 38f53074178fc3ed9877935f81e6b393c4405571 Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Wed, 21 Jul 2021 20:25:26 +0200 Subject: [PATCH] Start migration --- Cargo.lock | 2043 ----------------- crates/eww/src/app.rs | 6 +- crates/eww/src/config/element.rs | 2 +- crates/eww/src/config/eww_config.rs | 304 +-- crates/eww/src/config/inbuilt.rs | 14 +- crates/eww/src/config/mod.rs | 2 +- crates/eww/src/config/script_var.rs | 12 +- crates/eww/src/config/window_definition.rs | 170 +- crates/eww/src/config/window_geometry.rs | 2 +- crates/eww/src/eww_state.rs | 22 +- crates/eww/src/main.rs | 1 - crates/eww/src/opts.rs | 8 +- crates/eww/src/script_var_handler.rs | 4 +- crates/eww/src/value/attr_value/attr_value.rs | 209 -- .../src/value/attr_value/attr_value_expr.rs | 244 -- crates/eww/src/value/attr_value/mod.rs | 5 - crates/eww/src/value/attr_value/parser.rs | 224 -- crates/eww/src/value/coords.rs | 107 - crates/eww/src/value/mod.rs | 46 - crates/eww/src/value/primitive.rs | 188 -- crates/eww/src/widgets/mod.rs | 6 +- crates/eww/src/widgets/widget_definitions.rs | 1 - crates/eww/src/widgets/widget_node.rs | 2 +- crates/simplexpr/src/ast.rs | 6 + crates/simplexpr/src/dynval.rs | 4 +- crates/simplexpr/src/error.rs | 4 +- crates/yuck/Cargo.toml | 1 + crates/yuck/examples/validation.rs | 6 +- crates/yuck/src/config/attributes.rs | 6 +- crates/yuck/src/config/config.rs | 8 +- crates/yuck/src/config/mod.rs | 4 +- .../yuck/src/config/script_var_definition.rs | 2 +- crates/yuck/src/error.rs | 6 +- 33 files changed, 149 insertions(+), 3520 deletions(-) delete mode 100644 Cargo.lock delete mode 100644 crates/eww/src/value/attr_value/attr_value.rs delete mode 100644 crates/eww/src/value/attr_value/attr_value_expr.rs delete mode 100644 crates/eww/src/value/attr_value/mod.rs delete mode 100644 crates/eww/src/value/attr_value/parser.rs delete mode 100644 crates/eww/src/value/coords.rs delete mode 100644 crates/eww/src/value/mod.rs delete mode 100644 crates/eww/src/value/primitive.rs diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 2b142b2..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,2043 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "ahash" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi", -] - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "anyhow" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" - -[[package]] -name = "anymap" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "async-stream" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a26cb53174ddd320edfff199a853f93d571f48eeb4dde75e67a9a3dbb7b7e5e" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db134ba52475c060f3329a8ef0f8786d6b872ed01515d4b79c162e5798da1340" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "atk" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812b4911e210bd51b24596244523c856ca749e6223c50a7fbbba3f89ee37c426" -dependencies = [ - "atk-sys", - "bitflags", - "glib", - "glib-sys", - "gobject-sys", - "libc", -] - -[[package]] -name = "atk-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f530e4af131d94cc4fa15c5c9d0348f0ef28bac64ba660b6b2a1cf2605dedfce" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "beef" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "474a626a67200bd107d44179bb3d4fc61891172d11696609264589be6a0e6a43" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "bitvec" -version = "0.19.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "bytes" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" - -[[package]] -name = "cairo-rs" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5c0f2e047e8ca53d0ff249c54ae047931d7a6ebe05d00af73e0ffeb6e34bdb8" -dependencies = [ - "bitflags", - "cairo-sys-rs", - "glib", - "glib-sys", - "gobject-sys", - "libc", - "thiserror", -] - -[[package]] -name = "cairo-sys-rs" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ed2639b9ad5f1d6efa76de95558e11339e7318426d84ac4890b86c03e828ca7" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - -[[package]] -name = "cc" -version = "1.0.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "ansi_term 0.11.0", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "codemap" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e769b5c8c8283982a987c6e948e540254f1058d5a74b8794914d4ef5fc2a24" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation-sys" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" - -[[package]] -name = "crossbeam-channel" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278" -dependencies = [ - "autocfg", - "cfg-if", - "lazy_static", -] - -[[package]] -name = "ctor" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d" -dependencies = [ - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "debug_stub_derive" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496b7f8a2f853313c3ca370641d7ff3e42c32974fdccda8f0684599ed0a3ff6b" -dependencies = [ - "quote 0.3.15", - "syn 0.11.11", -] - -[[package]] -name = "derive_more" -version = "0.99.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b1b72f1263f214c0f823371768776c4f5841b942c9883aa8e5ec584fd0ba6" -dependencies = [ - "convert_case", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "diff" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" - -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - -[[package]] -name = "dyn-clone" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "env_logger" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "eww" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-stream", - "base64", - "bincode", - "cairo-sys-rs", - "debug_stub_derive", - "derive_more", - "dyn-clone", - "extend", - "futures-core", - "futures-util", - "gdk", - "gdk-pixbuf", - "gdkx11", - "gio", - "glib", - "grass", - "gtk", - "gtk-layer-shell", - "gtk-layer-shell-sys", - "itertools 0.10.0", - "lazy_static", - "libc", - "log", - "maplit", - "nix", - "nom", - "notify", - "num", - "pretty_assertions", - "pretty_env_logger", - "regex", - "roxmltree", - "serde", - "serde_json", - "simple-signal", - "smart-default", - "structopt", - "sysinfo", - "tokio", - "tokio-stream", - "tokio-util", - "unescape", - "wait-timeout", - "x11rb", -] - -[[package]] -name = "extend" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2feaa8e332f0db2f08788707dc550075aab8e6d20ffc85958e1174e22887d11" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "filetime" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "winapi", -] - -[[package]] -name = "fsevent" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97f347202c95c98805c216f9e1df210e8ebaec9fdb2365700a43c10797a35e63" -dependencies = [ - "bitflags", - "fsevent-sys", -] - -[[package]] -name = "fsevent-sys" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a29c77f1ca394c3e73a9a5d24cfcabb734682d9634fc398f2204a63c994120" -dependencies = [ - "libc", -] - -[[package]] -name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - -[[package]] -name = "futures" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815" - -[[package]] -name = "futures-executor" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04" - -[[package]] -name = "futures-macro" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "futures-sink" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23" - -[[package]] -name = "futures-task" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc" - -[[package]] -name = "futures-util" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "proc-macro-hack", - "proc-macro-nested", - "slab", -] - -[[package]] -name = "gdk" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db00839b2a68a7a10af3fa28dfb3febaba3a20c3a9ac2425a33b7df1f84a6b7d" -dependencies = [ - "bitflags", - "cairo-rs", - "cairo-sys-rs", - "gdk-pixbuf", - "gdk-sys", - "gio", - "gio-sys", - "glib", - "glib-sys", - "gobject-sys", - "libc", - "pango", -] - -[[package]] -name = "gdk-pixbuf" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6dae3cb99dd49b758b88f0132f8d401108e63ae8edd45f432d42cdff99998a" -dependencies = [ - "gdk-pixbuf-sys", - "gio", - "gio-sys", - "glib", - "glib-sys", - "gobject-sys", - "libc", -] - -[[package]] -name = "gdk-pixbuf-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bfe468a7f43e97b8d193a762b6c5cf67a7d36cacbc0b9291dbcae24bfea1e8f" -dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "gdk-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9653cfc500fd268015b1ac055ddbc3df7a5c9ea3f4ccef147b3957bd140d69" -dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "pkg-config", - "system-deps", -] - -[[package]] -name = "gdkx11" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89606baa221f9b8d8aa81924fd448c6b107d20de949f0fbf9a4ec203bb54b63" -dependencies = [ - "bitflags", - "gdk", - "gdk-pixbuf", - "gdk-pixbuf-sys", - "gdk-sys", - "gdkx11-sys", - "gio", - "gio-sys", - "glib", - "glib-sys", - "gobject-sys", - "libc", - "pango", - "x11", -] - -[[package]] -name = "gdkx11-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6710388d530f3178ccbeb65cbafdf497a5772c4409eaf574ee9fa461af0a3d09" -dependencies = [ - "gdk-pixbuf-sys", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "system-deps", - "x11", -] - -[[package]] -name = "gethostname" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gio" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb60242bfff700772dae5d9e3a1f7aa2e4ebccf18b89662a16acb2822568561" -dependencies = [ - "bitflags", - "futures", - "futures-channel", - "futures-core", - "futures-io", - "futures-util", - "gio-sys", - "glib", - "glib-sys", - "gobject-sys", - "libc", - "once_cell", - "thiserror", -] - -[[package]] -name = "gio-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e24fb752f8f5d2cf6bbc2c606fd2bc989c81c5e2fe321ab974d54f8b6344eac" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", - "winapi", -] - -[[package]] -name = "glib" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c685013b7515e668f1b57a165b009d4d28cb139a8a989bbd699c10dad29d0c5" -dependencies = [ - "bitflags", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "futures-util", - "glib-macros", - "glib-sys", - "gobject-sys", - "libc", - "once_cell", -] - -[[package]] -name = "glib-macros" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41486a26d1366a8032b160b59065a59fb528530a46a49f627e7048fb8c064039" -dependencies = [ - "anyhow", - "heck", - "itertools 0.9.0", - "proc-macro-crate", - "proc-macro-error", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "glib-sys" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1" -dependencies = [ - "libc", - "system-deps", -] - -[[package]] -name = "gobject-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - -[[package]] -name = "grass" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8209e6832a1f93e15adca845b43af12ead0cb8221fb2ef615ca84c75e54af1a" -dependencies = [ - "beef", - "clap", - "codemap", - "indexmap", - "lasso", - "num-bigint 0.3.2", - "num-rational 0.3.2", - "num-traits", - "once_cell", - "peekmore", - "phf", - "rand", -] - -[[package]] -name = "gtk" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f022f2054072b3af07666341984562c8e626a79daa8be27b955d12d06a5ad6a" -dependencies = [ - "atk", - "bitflags", - "cairo-rs", - "cairo-sys-rs", - "cc", - "gdk", - "gdk-pixbuf", - "gdk-pixbuf-sys", - "gdk-sys", - "gio", - "gio-sys", - "glib", - "glib-sys", - "gobject-sys", - "gtk-sys", - "libc", - "once_cell", - "pango", - "pango-sys", - "pkg-config", -] - -[[package]] -name = "gtk-layer-shell" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb41868e4305f14a5b5bc0d5a3fcc0553d3a24f1f176f93c7e136290eaa3b77" -dependencies = [ - "bitflags", - "gdk", - "glib", - "glib-sys", - "gtk", - "gtk-layer-shell-sys", - "libc", -] - -[[package]] -name = "gtk-layer-shell-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3c2ad4c131bf8e6870686615eb9897ad8c02ca0d4354c575f0d74acb429a0b" -dependencies = [ - "gdk-sys", - "glib-sys", - "gtk-sys", - "libc", - "system-deps", -] - -[[package]] -name = "gtk-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89acda6f084863307d948ba64a4b1ef674e8527dddab147ee4cdcc194c880457" -dependencies = [ - "atk-sys", - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "system-deps", -] - -[[package]] -name = "hashbrown" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" -dependencies = [ - "ahash", - "autocfg", -] - -[[package]] -name = "hashbrown" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" - -[[package]] -name = "heck" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" -dependencies = [ - "libc", -] - -[[package]] -name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] - -[[package]] -name = "indexmap" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" -dependencies = [ - "autocfg", - "hashbrown 0.9.1", -] - -[[package]] -name = "inotify" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19f57db1baad9d09e43a3cd76dcf82ebdafd37d75c9498b87762dba77c93f15" -dependencies = [ - "bitflags", - "inotify-sys", - "libc", -] - -[[package]] -name = "inotify-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" -dependencies = [ - "libc", -] - -[[package]] -name = "instant" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" - -[[package]] -name = "lasso" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf1a626ea51398f5acf36666c8046ff4bfd048aab88e92db676d2a6eac8805d0" -dependencies = [ - "hashbrown 0.8.2", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lexical-core" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" -dependencies = [ - "arrayvec", - "bitflags", - "cfg-if", - "ryu", - "static_assertions", -] - -[[package]] -name = "libc" -version = "0.2.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" - -[[package]] -name = "lock_api" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - -[[package]] -name = "memchr" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" - -[[package]] -name = "memoffset" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mio" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "nix" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" -dependencies = [ - "bitflags", - "cc", - "cfg-if", - "libc", -] - -[[package]] -name = "nom" -version = "6.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" -dependencies = [ - "bitvec", - "funty", - "lexical-core", - "memchr", - "version_check", -] - -[[package]] -name = "notify" -version = "5.0.0-pre.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebe7699a0f8c5759450716ee03d231685c22b4fe8f406c42c22e0ad94d40ce7" -dependencies = [ - "anymap", - "bitflags", - "crossbeam-channel", - "filetime", - "fsevent", - "fsevent-sys", - "inotify", - "libc", - "mio", - "walkdir", - "winapi", -] - -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - -[[package]] -name = "num" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" -dependencies = [ - "num-bigint 0.4.0", - "num-complex", - "num-integer", - "num-iter", - "num-rational 0.4.0", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d0a3d5e207573f948a9e5376662aa743a2ea13f7c50a554d7af443a73fbfeba" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" -dependencies = [ - "autocfg", - "num-bigint 0.3.2", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" -dependencies = [ - "autocfg", - "num-bigint 0.4.0", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" - -[[package]] -name = "output_vt100" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" -dependencies = [ - "winapi", -] - -[[package]] -name = "pango" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9937068580bebd8ced19975938573803273ccbcbd598c58d4906efd4ac87c438" -dependencies = [ - "bitflags", - "glib", - "glib-sys", - "gobject-sys", - "libc", - "once_cell", - "pango-sys", -] - -[[package]] -name = "pango-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d2650c8b62d116c020abd0cea26a4ed96526afda89b1c4ea567131fdefc890" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "parking_lot" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "peekmore" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4089f831c514cbf080bd19bfce702f7a2de250492730d419204af6710ba19316" -dependencies = [ - "smallvec", -] - -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_macros", - "phf_shared", - "proc-macro-hack", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared", - "rand", -] - -[[package]] -name = "phf_macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro-hack", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" - -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "pretty_assertions" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cab0e7c02cf376875e9335e0ba1da535775beb5450d21e1dffca068818ed98b" -dependencies = [ - "ansi_term 0.12.1", - "ctor", - "diff", - "output_vt100", -] - -[[package]] -name = "pretty_env_logger" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" -dependencies = [ - "env_logger", - "log", -] - -[[package]] -name = "proc-macro-crate" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - -[[package]] -name = "proc-macro2" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" -dependencies = [ - "unicode-xid 0.2.2", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", - "rand_pcg", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rayon" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "roxmltree" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b" -dependencies = [ - "xmlparser", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "serde" -version = "1.0.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "serde_json" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "signal-hook-registry" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" -dependencies = [ - "libc", -] - -[[package]] -name = "simple-signal" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f7da44adcc42667d57483bd93f81295f27d66897804b757573b61b6f13288b" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "siphasher" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" - -[[package]] -name = "slab" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" - -[[package]] -name = "smallvec" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" - -[[package]] -name = "smart-default" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "strum" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b" - -[[package]] -name = "strum_macros" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" -dependencies = [ - "heck", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid 0.0.4", -] - -[[package]] -name = "syn" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "unicode-xid 0.2.2", -] - -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid 0.0.4", -] - -[[package]] -name = "sysinfo" -version = "0.16.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567e910ef0207be81a4e1bb0491e9a8d9866cf45b20fe1a52c03d347da9ea51b" -dependencies = [ - "cfg-if", - "core-foundation-sys", - "doc-comment", - "libc", - "ntapi", - "once_cell", - "rayon", - "winapi", -] - -[[package]] -name = "system-deps" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b" -dependencies = [ - "heck", - "pkg-config", - "strum", - "strum_macros", - "thiserror", - "toml", - "version-compare", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "tokio" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5" -dependencies = [ - "autocfg", - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "once_cell", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-macros" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" -dependencies = [ - "proc-macro2", - "quote 1.0.9", - "syn 1.0.72", -] - -[[package]] -name = "tokio-stream" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e177a5d8c3bf36de9ebe6d58537d8879e964332f93fb3339e43f618c81361af0" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "940a12c99365c31ea8dd9ba04ec1be183ffe4920102bb7122c2f515437601e8e" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" -dependencies = [ - "serde", -] - -[[package]] -name = "unescape" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" - -[[package]] -name = "unicode-segmentation" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" - -[[package]] -name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version-compare" -version = "0.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-wsapoll" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "wyz" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" - -[[package]] -name = "x11" -version = "2.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ecd092546cb16f25783a5451538e73afc8d32e242648d54f4ae5459ba1e773" -dependencies = [ - "libc", - "pkg-config", -] - -[[package]] -name = "x11rb" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ffb080b3f2f616242a4eb8e7d325035312127901025b0052bc3154a282d0f19" -dependencies = [ - "gethostname", - "nix", - "winapi", - "winapi-wsapoll", -] - -[[package]] -name = "xmlparser" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" diff --git a/crates/eww/src/app.rs b/crates/eww/src/app.rs index 367d654..c89444f 100644 --- a/crates/eww/src/app.rs +++ b/crates/eww/src/app.rs @@ -3,7 +3,7 @@ use crate::{ config::{window_definition::WindowName, AnchorPoint}, display_backend, eww_state, script_var_handler::*, - value::{Coords, NumWithUnit, PrimVal, VarName}, + dynval::{Coords, NumWithUnit, DynVal, VarName}, EwwPaths, }; use anyhow::*; @@ -38,7 +38,7 @@ pub type DaemonResponseReceiver = tokio::sync::mpsc::UnboundedReceiver), + UpdateVars(Vec<(VarName, DynVal)>), ReloadConfigAndCss(DaemonResponseSender), UpdateConfig(config::EwwConfig), UpdateCss(String), @@ -199,7 +199,7 @@ impl App { gtk::main_quit(); } - fn update_state(&mut self, fieldname: VarName, value: PrimVal) { + fn update_state(&mut self, fieldname: VarName, value: DynVal) { self.eww_state.update_variable(fieldname, value) } diff --git a/crates/eww/src/config/element.rs b/crates/eww/src/config/element.rs index 51052fe..98d9445 100644 --- a/crates/eww/src/config/element.rs +++ b/crates/eww/src/config/element.rs @@ -4,7 +4,7 @@ use regex::Regex; use std::ops::Range; use crate::{ - value::{AttrName, AttrVal}, + dynval::{AttrName, AttrVal}, with_text_pos_context, }; use maplit::hashmap; diff --git a/crates/eww/src/config/eww_config.rs b/crates/eww/src/config/eww_config.rs index 88a2494..a6644b8 100644 --- a/crates/eww/src/config/eww_config.rs +++ b/crates/eww/src/config/eww_config.rs @@ -1,50 +1,56 @@ use anyhow::*; use std::collections::HashMap; - -use crate::{ - util, - value::{PrimVal, VarName}, +use yuck::{ + config::{ + script_var_definition::ScriptVarDefinition, widget_definition::WidgetDefinition, window_definition::WindowDefinition, + }, + parser::from_ast::FromAst, + value::VarName, }; -use super::{ - element::WidgetDefinition, - xml_ext::{XmlElement, XmlNode}, - EwwWindowDefinition, RawEwwWindowDefinition, ScriptVar, WindowName, -}; +use simplexpr::dynval::DynVal; + use std::path::PathBuf; /// Eww configuration structure. #[derive(Debug, Clone)] pub struct EwwConfig { widgets: HashMap, - windows: HashMap, - initial_variables: HashMap, - script_vars: HashMap, + windows: HashMap, + initial_variables: HashMap, + script_vars: HashMap, pub filepath: PathBuf, } impl EwwConfig { pub fn read_from_file>(path: P) -> Result { - Self::generate(RawEwwConfig::read_from_file(path)?) + let content = std::fs::read_to_string(path)?; + let ast = yuck::parser::parse_string(0, &content)?; + let config = yuck::config::Config::from_ast(ast)?; + Self::generate(config) } - pub fn generate(conf: RawEwwConfig) -> Result { - let RawEwwConfig { windows, initial_variables, script_vars, filepath, widgets } = conf; + pub fn generate(config: yuck::config::Config) -> Result { Ok(EwwConfig { - windows: windows + windows: config + .window_definitions .into_iter() .map(|(name, window)| { - Ok((name, EwwWindowDefinition::generate(&widgets, window).context("Failed expand window definition")?)) + Ok(( + name, + WindowDefinition::generate(&config.widget_definitions, window) + .context("Failed expand window definition")?, + )) }) .collect::>>()?, - widgets, - initial_variables, - script_vars, - filepath, + widgets: config.widget_definitions, + initial_variables: config.var_definitions.into_iter().map(|(k, v)| (k, v.initial_value)).collect(), + script_vars: config.script_vars, + filepath: todo!(), }) } // TODO this is kinda ugly - pub fn generate_initial_state(&self) -> Result> { + pub fn generate_initial_state(&self) -> Result> { let mut vars = self.script_vars.iter().map(|var| Ok((var.0.clone(), var.1.initial_value()?))).collect::>>()?; vars.extend(self.initial_variables.clone()); @@ -68,222 +74,40 @@ impl EwwConfig { } } -/// Raw Eww configuration, before expanding widget usages. -#[derive(Debug, Clone)] -pub struct RawEwwConfig { - widgets: HashMap, - windows: HashMap, - initial_variables: HashMap, - script_vars: HashMap, - pub filepath: PathBuf, -} +// Raw Eww configuration, before expanding widget usages. +//#[derive(Debug, Clone)] +// pub struct RawEwwConfig { +// widgets: HashMap, +// windows: HashMap, +// initial_variables: HashMap, +// script_vars: HashMap, +// pub filepath: PathBuf, +//} -impl RawEwwConfig { - pub fn merge_includes(mut eww_config: RawEwwConfig, includes: Vec) -> Result { - let config_path = eww_config.filepath.clone(); - let log_conflict = |what: &str, conflict: &str, included_path: &std::path::PathBuf| { - log::error!( - "{} '{}' defined twice (defined in {} and in {})", - what, - conflict, - config_path.display(), - included_path.display() - ); - }; - for included_config in includes { - for conflict in util::extend_safe(&mut eww_config.widgets, included_config.widgets) { - log_conflict("widget", &conflict, &included_config.filepath) - } - for conflict in util::extend_safe(&mut eww_config.windows, included_config.windows) { - log_conflict("window", &conflict.to_string(), &included_config.filepath) - } - for conflict in util::extend_safe(&mut eww_config.script_vars, included_config.script_vars) { - log_conflict("script-var", &conflict.to_string(), &included_config.filepath) - } - for conflict in util::extend_safe(&mut eww_config.initial_variables, included_config.initial_variables) { - log_conflict("var", &conflict.to_string(), &included_config.filepath) - } - } - Ok(eww_config) - } - - pub fn read_from_file>(path: P) -> Result { - let result: Result<_> = try { - let content = util::replace_env_var_references(std::fs::read_to_string(path.as_ref())?); - let content = content.replace("&", "&"); - let document = roxmltree::Document::parse(&content).map_err(|e| anyhow!(e))?; - let root_node = XmlNode::from(document.root_element()); - let root_element = root_node.as_element()?; - - let (config, included_paths) = Self::from_xml_element(root_element.clone(), path.as_ref()) - .with_context(|| format!("Error parsing eww config file {}", path.as_ref().display()))?; - - let parsed_includes = included_paths - .into_iter() - .map(Self::read_from_file) - .collect::>>() - .with_context(|| format!("Included in {}", path.as_ref().display()))?; - - Self::merge_includes(config, parsed_includes) - .context("Failed to merge included files into parent configuration file")? - }; - result.with_context(|| format!("Failed to load eww config file {}", path.as_ref().display())) - } - - pub fn from_xml_element>(xml: XmlElement, path: P) -> Result<(Self, Vec)> { - let path = path.as_ref(); - - let included_paths = match xml.child("includes").ok() { - Some(tag) => tag - .child_elements() - .map(|child| { - crate::ensure_xml_tag_is!(child, "file"); - Ok(util::join_path_pretty(path, PathBuf::from(child.attr("path")?))) - }) - .collect::>>()?, - None => Default::default(), - }; - - let definitions = match xml.child("definitions").ok() { - Some(tag) => tag - .child_elements() - .map(|child| { - let def = WidgetDefinition::from_xml_element(&child).with_context(|| { - format!("Error parsing widget definition at {}:{}", path.display(), &child.text_pos()) - })?; - Ok((def.name.clone(), def)) - }) - .collect::>>()?, - None => Default::default(), - }; - - let windows = match xml.child("windows").ok() { - Some(tag) => tag - .child_elements() - .map(|child| { - let def = RawEwwWindowDefinition::from_xml_element(&child).with_context(|| { - format!("Error parsing window definition at {}:{}", path.display(), &child.text_pos()) - })?; - Ok((def.name.to_owned(), def)) - }) - .collect::>>()?, - None => Default::default(), - }; - - let (initial_variables, script_vars) = match xml.child("variables").ok() { - Some(tag) => parse_variables_block(tag)?, - None => Default::default(), - }; - - let config = RawEwwConfig { widgets: definitions, windows, initial_variables, script_vars, filepath: path.to_path_buf() }; - Ok((config, included_paths)) - } -} - -fn parse_variables_block(xml: XmlElement) -> Result<(HashMap, HashMap)> { - let mut normal_vars = HashMap::new(); - let mut script_vars = HashMap::new(); - for node in xml.child_elements() { - match node.tag_name() { - "var" => { - let value = node.only_child().map(|c| c.as_text_or_sourcecode()).unwrap_or_else(|_| String::new()); - normal_vars.insert(VarName(node.attr("name")?.to_owned()), PrimVal::from_string(value)); - } - "script-var" => { - let script_var = ScriptVar::from_xml_element(node)?; - script_vars.insert(script_var.name().clone(), script_var); - } - _ => bail!("Illegal element in variables block: {}", node.as_tag_string()), - } - } - - // Extends the variables with the predefined variables - let inbuilt = crate::config::inbuilt::get_inbuilt_vars(); - for i in util::extend_safe(&mut script_vars, inbuilt) { - log::error!( - "script-var '{}' defined twice (defined in your config and in the eww included variables)\nHint: don't define any \ - varible like any of these: https://elkowar.github.io/eww/main/magic-variables-documenation/", - i, - ); - } - - Ok((normal_vars, script_vars)) -} - -#[cfg(test)] -mod test { - use crate::config::{RawEwwConfig, XmlNode}; - use std::collections::HashMap; - - #[test] - fn test_merge_includes() { - let input1 = r#" - - - - - {{var1}} - - - - - - var1 - - - - - - - - - - - - "#; - let input2 = r#" - - - - - {{var2}} - - - - - var2 - - - - - - - - - - - - "#; - - let document1 = roxmltree::Document::parse(&input1).unwrap(); - let document2 = roxmltree::Document::parse(input2).unwrap(); - let config1 = - RawEwwConfig::from_xml_element(XmlNode::from(document1.root_element()).as_element().unwrap().clone(), "").unwrap().0; - let config2 = - RawEwwConfig::from_xml_element(XmlNode::from(document2.root_element()).as_element().unwrap().clone(), "").unwrap().0; - let base_config = RawEwwConfig { - widgets: HashMap::new(), - windows: HashMap::new(), - initial_variables: HashMap::new(), - script_vars: HashMap::new(), - filepath: "test_path".into(), - }; - - let merged_config = RawEwwConfig::merge_includes(base_config, vec![config1, config2]).unwrap(); - - assert_eq!(merged_config.widgets.len(), 2); - assert_eq!(merged_config.windows.len(), 2); - assert_eq!(merged_config.initial_variables.len(), 2); - assert_eq!(merged_config.script_vars.len(), 6); - } -} +// impl RawEwwConfig { +// pub fn merge_includes(mut eww_config: RawEwwConfig, includes: Vec) -> Result { +// let config_path = eww_config.filepath.clone(); +// let log_conflict = |what: &str, conflict: &str, included_path: &std::path::PathBuf| { +// log::error!( +//"{} '{}' defined twice (defined in {} and in {})", +// what, +// conflict, +// config_path.display(), +// included_path.display() +//); +//}; +// for included_config in includes { +// for conflict in util::extend_safe(&mut eww_config.widgets, included_config.widgets) { +// log_conflict("widget", &conflict, &included_config.filepath) +//} +// for conflict in util::extend_safe(&mut eww_config.windows, included_config.windows) { +// log_conflict("window", &conflict.to_string(), &included_config.filepath) +//} +// for conflict in util::extend_safe(&mut eww_config.script_vars, included_config.script_vars) { +// log_conflict("script-var", &conflict.to_string(), &included_config.filepath) +//} +// for conflict in util::extend_safe(&mut eww_config.initial_variables, included_config.initial_variables) { +// log_conflict("var", &conflict.to_string(), &included_config.filepath) +//} +// Ok(eww_config) +//} diff --git a/crates/eww/src/config/inbuilt.rs b/crates/eww/src/config/inbuilt.rs index cd9e117..dd9efba 100644 --- a/crates/eww/src/config/inbuilt.rs +++ b/crates/eww/src/config/inbuilt.rs @@ -1,6 +1,6 @@ use crate::{ config::{system_stats::*, PollScriptVar, ScriptVar, VarSource}, - value::{PrimVal as PrimitiveValue, VarName}, + dynval::{DynVal as PrimitiveValue, VarName}, }; use std::{collections::HashMap, time::Duration}; @@ -20,16 +20,16 @@ macro_rules! builtin_vars { pub fn get_inbuilt_vars() -> HashMap { builtin_vars! {Duration::new(2, 0), // @desc EWW_TEMPS - Heat of the components in Celcius\nExample: `{{(CPU_TEMPS.core_1 + CPU_TEMPS.core_2) / 2}}` - "EWW_TEMPS" => || Ok(PrimitiveValue::from(cores())), + "EWW_TEMPS" => || Ok(Primitivedynval::from(cores())), // @desc EWW_RAM - The current RAM + Swap usage - "EWW_RAM" => || Ok(PrimitiveValue::from(format!("{:.2}", ram()))), + "EWW_RAM" => || Ok(Primitivedynval::from(format!("{:.2}", ram()))), // @desc EWW_DISK - Information on on all mounted partitions (Might report inaccurately on some filesystems, like btrfs)\nExample: `{{EWW_DISK["/"]}}` - "EWW_DISK" => || Ok(PrimitiveValue::from(disk())), + "EWW_DISK" => || Ok(Primitivedynval::from(disk())), // @desc EWW_BATTERY - Battery capacity in procent of the main battery - "EWW_BATTERY" => || Ok(PrimitiveValue::from( + "EWW_BATTERY" => || Ok(Primitivedynval::from( match get_battery_capacity() { Err(e) => { log::error!("Couldn't get the battery capacity: {:?}", e); @@ -40,9 +40,9 @@ pub fn get_inbuilt_vars() -> HashMap { )), // @desc EWW_CPU_USAGE - Average CPU usage (all cores) since the last update (No MacOS support) - "EWW_CPU_USAGE" => || Ok(PrimitiveValue::from(get_avg_cpu_usage())), + "EWW_CPU_USAGE" => || Ok(Primitivedynval::from(get_avg_cpu_usage())), // @desc EWW_NET - Bytes up/down on all interfaces - "EWW_NET" => || Ok(PrimitiveValue::from(net())), + "EWW_NET" => || Ok(Primitivedynval::from(net())), } } diff --git a/crates/eww/src/config/mod.rs b/crates/eww/src/config/mod.rs index 361c337..bacbf46 100644 --- a/crates/eww/src/config/mod.rs +++ b/crates/eww/src/config/mod.rs @@ -1,6 +1,6 @@ use crate::{ util, - value::{PrimVal, VarName}, + dynval::{DynVal, VarName}, }; use anyhow::*; diff --git a/crates/eww/src/config/script_var.rs b/crates/eww/src/config/script_var.rs index b3aeda8..0f965e6 100644 --- a/crates/eww/src/config/script_var.rs +++ b/crates/eww/src/config/script_var.rs @@ -9,7 +9,7 @@ use super::*; #[derive(Clone, Debug, PartialEq, Eq)] pub enum VarSource { Shell(String), - Function(fn() -> Result), + Function(fn() -> Result), } #[derive(Clone, Debug, PartialEq, Eq)] pub struct PollScriptVar { @@ -19,7 +19,7 @@ pub struct PollScriptVar { } impl PollScriptVar { - pub fn run_once(&self) -> Result { + pub fn run_once(&self) -> Result { match &self.command { VarSource::Shell(x) => run_command(x), VarSource::Function(x) => x(), @@ -47,7 +47,7 @@ impl ScriptVar { } } - pub fn initial_value(&self) -> Result { + pub fn initial_value(&self) -> Result { match self { ScriptVar::Poll(x) => match &x.command { VarSource::Function(f) => f().with_context(|| format!("Failed to compute initial value for {}", &self.name())), @@ -55,7 +55,7 @@ impl ScriptVar { run_command(f).with_context(|| format!("Failed to compute initial value for {}", &self.name())) } }, - ScriptVar::Tail(_) => Ok(PrimVal::from_string(String::new())), + ScriptVar::Tail(_) => Ok(DynVal::from_string(String::new())), } } @@ -74,9 +74,9 @@ impl ScriptVar { } /// Run a command and get the output -fn run_command(cmd: &str) -> Result { +fn run_command(cmd: &str) -> Result { log::debug!("Running command: {}", cmd); let output = String::from_utf8(Command::new("/bin/sh").arg("-c").arg(cmd).output()?.stdout)?; let output = output.trim_matches('\n'); - Ok(PrimVal::from(output)) + Ok(DynVal::from(output)) } diff --git a/crates/eww/src/config/window_definition.rs b/crates/eww/src/config/window_definition.rs index 1e28336..a8ac3b2 100644 --- a/crates/eww/src/config/window_definition.rs +++ b/crates/eww/src/config/window_definition.rs @@ -1,9 +1,14 @@ use super::*; -use crate::{ensure_xml_tag_is, value::NumWithUnit, widgets::widget_node}; +use crate::{dynval::NumWithUnit, ensure_xml_tag_is, widgets::widget_node}; use derive_more::*; use serde::{Deserialize, Serialize}; use smart_default::SmartDefault; use std::{collections::HashMap, str::FromStr}; +use yuck::config::{ + backend_window_options::StrutDefinition, + window_definition::{WindowDefinition, WindowStacking}, + window_geometry::WindowGeometry, +}; #[derive(Debug, Clone, PartialEq)] pub enum EwwWindowType { @@ -36,31 +41,31 @@ impl Default for EwwWindowType { /// **Use this** rather than `[RawEwwWindowDefinition]`. #[derive(Debug, Clone)] pub struct EwwWindowDefinition { - pub name: WindowName, - - pub geometry: EwwWindowGeometry, + pub name: String, + + pub geometry: WindowGeometry, pub stacking: WindowStacking, - pub screen_number: Option, + pub monitor_number: Option, pub widget: Box, pub focusable: bool, - + #[cfg(feature = "x11")] pub window_type: EwwWindowType, - + #[cfg(feature = "x11")] pub struts: StrutDefinition, - + #[cfg(feature = "wayland")] pub exclusive: bool, } impl EwwWindowDefinition { - pub fn generate(defs: &HashMap, window: RawEwwWindowDefinition) -> Result { + pub fn generate(defs: &HashMap, window: WindowDefinition) -> Result { Ok(EwwWindowDefinition { name: window.name, geometry: window.geometry, stacking: window.stacking, - screen_number: window.screen_number, + monitor_number: window.screen_number, widget: widget_node::generate_generic_widget_node(defs, &HashMap::new(), window.widget)?, focusable: window.focusable, #[cfg(feature = "x11")] @@ -72,148 +77,3 @@ impl EwwWindowDefinition { }) } } - -/// Window-definition storing the raw WidgetUse, as received directly from parsing. -#[derive(Debug, Clone, PartialEq)] -pub struct RawEwwWindowDefinition { - pub name: WindowName, - pub geometry: EwwWindowGeometry, - pub stacking: WindowStacking, - pub screen_number: Option, - pub widget: WidgetUse, - pub focusable: bool, - - #[cfg(feature = "x11")] - pub window_type: EwwWindowType, - - #[cfg(feature = "x11")] - pub struts: StrutDefinition, - - #[cfg(feature = "wayland")] - pub exclusive: bool, -} - -impl RawEwwWindowDefinition { - pub fn from_xml_element(xml: &XmlElement) -> Result { - ensure_xml_tag_is!(xml, "window"); - let stacking: WindowStacking = xml.parse_optional_attr("stacking")?.unwrap_or_default(); - - // TODO maybe rename this to monitor? - let focusable = xml.parse_optional_attr("focusable")?; - let screen_number = xml.parse_optional_attr("screen")?; - - #[cfg(feature = "x11")] - let struts: Option = - xml.child("reserve").ok().map(StrutDefinition::from_xml_element).transpose().context("Failed to parse ")?; - - Ok(RawEwwWindowDefinition { - name: WindowName(xml.attr("name")?), - geometry: match xml.child("geometry") { - Ok(node) => EwwWindowGeometry::from_xml_element(node)?, - Err(_) => EwwWindowGeometry::default(), - }, - #[cfg(feature = "x11")] - window_type: match xml.attr("windowtype") { - Ok(v) => EwwWindowType::from_str(&v)?, - Err(_) => match struts { - Some(_) => EwwWindowType::Dock, - None => Default::default(), - }, - }, - widget: WidgetUse::from_xml_node(xml.child("widget")?.only_child()?)?, - stacking, - screen_number, - focusable: focusable.unwrap_or(false), - #[cfg(feature = "x11")] - struts: struts.unwrap_or_default(), - #[cfg(feature = "wayland")] - exclusive: xml.parse_optional_attr("exclusive")?.unwrap_or_default(), - }) - } -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq, smart_default::SmartDefault)] -pub enum Side { - #[default] - Top, - Left, - Right, - Bottom, -} - -impl std::str::FromStr for Side { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - match s { - "l" | "left" => Ok(Side::Left), - "r" | "right" => Ok(Side::Right), - "t" | "top" => Ok(Side::Top), - "b" | "bottom" => Ok(Side::Bottom), - _ => Err(anyhow!("Failed to parse {} as valid side. Must be one of \"left\", \"right\", \"top\", \"bottom\"", s)), - } - } -} - -// Surface definition if the backend for X11 is enable -#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] -pub struct StrutDefinition { - pub side: Side, - pub dist: NumWithUnit, -} - -impl StrutDefinition { - pub fn from_xml_element(xml: XmlElement) -> Result { - Ok(StrutDefinition { side: xml.attr("side")?.parse()?, dist: xml.attr("distance")?.parse()? }) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, derive_more::Display, SmartDefault)] -pub enum WindowStacking { - #[default] - Foreground, - Background, - Bottom, - Overlay, -} - -impl std::str::FromStr for WindowStacking { - type Err = anyhow::Error; - - #[cfg(not(feature = "wayland"))] - fn from_str(s: &str) -> Result { - let s = s.to_lowercase(); - match s.as_str() { - "foreground" | "fg" | "f" => Ok(WindowStacking::Foreground), - "background" | "bg" | "b" => Ok(WindowStacking::Background), - _ => Err(anyhow!("Couldn't parse '{}' as window stacking, must be either foreground, fg, background or bg", s)), - } - } - - #[cfg(feature = "wayland")] - fn from_str(s: &str) -> Result { - let s = s.to_lowercase(); - match s.as_str() { - "foreground" | "fg" => Ok(WindowStacking::Foreground), - "background" | "bg" => Ok(WindowStacking::Background), - "bottom" | "bt" => Ok(WindowStacking::Bottom), - "overlay" | "ov" => Ok(WindowStacking::Overlay), - _ => Err(anyhow!( - "Couldn't parse '{}' as window stacking, must be either foreground, fg, background, bg, bottom, bt, overlay or \ - ov", - s - )), - } - } -} - -#[repr(transparent)] -#[derive(Clone, Hash, PartialEq, Eq, AsRef, FromStr, Display, Serialize, Deserialize, Default, From, DebugCustom)] -#[debug(fmt = "WindowName(\".0\")")] -pub struct WindowName(String); - -impl std::borrow::Borrow for WindowName { - fn borrow(&self) -> &str { - &self.0 - } -} diff --git a/crates/eww/src/config/window_geometry.rs b/crates/eww/src/config/window_geometry.rs index 4b68c35..75308d4 100644 --- a/crates/eww/src/config/window_geometry.rs +++ b/crates/eww/src/config/window_geometry.rs @@ -1,4 +1,4 @@ -use crate::value::Coords; +use crate::dynval::Coords; use anyhow::*; use serde::{Deserialize, Serialize}; use smart_default::SmartDefault; diff --git a/crates/eww/src/eww_state.rs b/crates/eww/src/eww_state.rs index 7f929e5..4160c1e 100644 --- a/crates/eww/src/eww_state.rs +++ b/crates/eww/src/eww_state.rs @@ -1,16 +1,16 @@ use crate::{ config::window_definition::WindowName, - value::{AttrName, AttrValElement, VarName}, + dynval::{AttrName, AttrValElement, VarName}, }; use anyhow::*; use std::{collections::HashMap, sync::Arc}; -use crate::value::{AttrVal, PrimVal}; +use crate::dynval::{AttrVal, DynVal}; /// Handler that gets executed to apply the necessary parts of the eww state to /// a gtk widget. These are created and initialized in EwwState::resolve. pub struct StateChangeHandler { - func: Box) -> Result<()> + 'static>, + func: Box) -> Result<()> + 'static>, unresolved_values: HashMap, } @@ -21,7 +21,7 @@ impl StateChangeHandler { /// Run the StateChangeHandler. /// [`state`] should be the global [EwwState::state]. - fn run_with_state(&self, state: &HashMap) { + fn run_with_state(&self, state: &HashMap) { let resolved_attrs = self .unresolved_values .clone() @@ -61,7 +61,7 @@ impl EwwWindowState { #[derive(Default)] pub struct EwwState { windows: HashMap, - variables_state: HashMap, + variables_state: HashMap, } impl std::fmt::Debug for EwwState { @@ -71,11 +71,11 @@ impl std::fmt::Debug for EwwState { } impl EwwState { - pub fn from_default_vars(defaults: HashMap) -> Self { + pub fn from_default_vars(defaults: HashMap) -> Self { EwwState { variables_state: defaults, ..EwwState::default() } } - pub fn get_variables(&self) -> &HashMap { + pub fn get_variables(&self) -> &HashMap { &self.variables_state } @@ -91,7 +91,7 @@ impl EwwState { /// Update the value of a variable, running all registered /// [StateChangeHandler]s. - pub fn update_variable(&mut self, key: VarName, value: PrimVal) { + pub fn update_variable(&mut self, key: VarName, value: DynVal) { self.variables_state.insert(key.clone(), value); // run all of the handlers @@ -103,12 +103,12 @@ impl EwwState { } /// Look up a single variable in the eww state, returning an `Err` when the value is not found. - pub fn lookup(&self, var_name: &VarName) -> Result<&PrimVal> { + pub fn lookup(&self, var_name: &VarName) -> Result<&DynVal> { self.variables_state.get(var_name).with_context(|| format!("Unknown variable '{}' referenced", var_name)) } /// resolves a value if possible, using the current eww_state. - pub fn resolve_once<'a>(&'a self, value: &'a AttrVal) -> Result { + pub fn resolve_once<'a>(&'a self, value: &'a AttrVal) -> Result { value .iter() .map(|element| match element { @@ -120,7 +120,7 @@ impl EwwState { /// Resolve takes a function that applies a set of fully resolved attribute /// values to it's gtk widget. - pub fn resolve) -> Result<()> + 'static + Clone>( + pub fn resolve) -> Result<()> + 'static + Clone>( &mut self, window_name: &WindowName, required_attributes: HashMap, diff --git a/crates/eww/src/main.rs b/crates/eww/src/main.rs index 3fd10e7..a39850c 100644 --- a/crates/eww/src/main.rs +++ b/crates/eww/src/main.rs @@ -29,7 +29,6 @@ pub mod opts; pub mod script_var_handler; pub mod server; pub mod util; -pub mod value; pub mod widgets; fn main() { diff --git a/crates/eww/src/opts.rs b/crates/eww/src/opts.rs index 5e84c99..d6ef99c 100644 --- a/crates/eww/src/opts.rs +++ b/crates/eww/src/opts.rs @@ -5,7 +5,7 @@ use structopt::StructOpt; use crate::{ app, config::{AnchorPoint, WindowName}, - value::{Coords, PrimVal, VarName}, + dynval::{Coords, DynVal, VarName}, }; /// Struct that gets generated from `RawOpt`. @@ -61,7 +61,7 @@ pub enum ActionWithServer { Update { /// variable_name="new_value"-pairs that will be updated #[structopt(parse(try_from_str = parse_var_update_arg))] - mappings: Vec<(VarName, PrimVal)>, + mappings: Vec<(VarName, DynVal)>, }, /// open a window @@ -142,11 +142,11 @@ impl From for Opt { } } -fn parse_var_update_arg(s: &str) -> Result<(VarName, PrimVal)> { +fn parse_var_update_arg(s: &str) -> Result<(VarName, DynVal)> { let (name, value) = s .split_once('=') .with_context(|| format!("arguments must be in the shape `variable_name=\"new_value\"`, but got: {}", s))?; - Ok((name.into(), PrimVal::from_string(value.to_owned()))) + Ok((name.into(), DynVal::from_string(value.to_owned()))) } impl ActionWithServer { diff --git a/crates/eww/src/script_var_handler.rs b/crates/eww/src/script_var_handler.rs index d867a2b..372a77b 100644 --- a/crates/eww/src/script_var_handler.rs +++ b/crates/eww/src/script_var_handler.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use crate::{ app, config, - value::{PrimVal, VarName}, + dynval::{DynVal, VarName}, }; use anyhow::*; use app::DaemonCommand; @@ -197,7 +197,7 @@ impl TailVarHandler { _ = handle.wait() => break, _ = cancellation_token.cancelled() => break, Ok(Some(line)) = stdout_lines.next_line() => { - let new_value = PrimVal::from_string(line.to_owned()); + let new_value = DynVal::from_string(line.to_owned()); evt_send.send(DaemonCommand::UpdateVars(vec![(var.name.to_owned(), new_value)]))?; } else => break, diff --git a/crates/eww/src/value/attr_value/attr_value.rs b/crates/eww/src/value/attr_value/attr_value.rs deleted file mode 100644 index c7359ab..0000000 --- a/crates/eww/src/value/attr_value/attr_value.rs +++ /dev/null @@ -1,209 +0,0 @@ -use anyhow::*; -use itertools::Itertools; -use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, fmt, iter::FromIterator}; - -use super::super::*; - -/// A value assigned to an attribute in a widget. -/// This can be a primitive String that contains any amount of variable -/// references, as would be generated by the string "foo {{var}} bar". -#[derive(Serialize, Deserialize, Clone, PartialEq, derive_more::Into, derive_more::From, Default)] -pub struct AttrVal(Vec); - -impl fmt::Display for AttrVal { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.iter().map(|x| format!("{}", x)).join("")) - } -} - -impl fmt::Debug for AttrVal { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "AttrValue({:?})", self.0) - } -} - -impl IntoIterator for AttrVal { - type IntoIter = std::vec::IntoIter; - type Item = AttrValElement; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -impl FromIterator for AttrVal { - fn from_iter>(iter: T) -> Self { - AttrVal(iter.into_iter().collect()) - } -} - -impl AttrVal { - pub fn from_primitive>(v: T) -> Self { - AttrVal(vec![AttrValElement::Primitive(v.into())]) - } - - pub fn from_var_ref>(v: T) -> Self { - AttrVal(vec![AttrValElement::Expr(AttrValExpr::VarRef(v.into()))]) - } - - pub fn iter(&self) -> std::slice::Iter { - self.0.iter() - } - - pub fn var_refs(&self) -> impl Iterator { - self.0.iter().filter_map(|x| Some(x.as_expr()?.var_refs())).flatten() - } - - /// resolve partially. - /// If a var-ref links to another var-ref, that other var-ref is used. - /// If a referenced variable is not found in the given hashmap, returns the var-ref unchanged. - pub fn resolve_one_level(self, variables: &HashMap) -> AttrVal { - self.into_iter() - .map(|entry| match entry { - AttrValElement::Expr(expr) => AttrValElement::Expr(expr.map_terminals_into(|child_expr| match child_expr { - AttrValExpr::VarRef(var_name) => match variables.get(&var_name) { - Some(value) => AttrValExpr::Literal(value.clone()), - None => AttrValExpr::VarRef(var_name), - }, - other => other, - })), - - _ => entry, - }) - .collect() - } - - /// resolve fully. - /// As the variables here have to be primitive values, - /// this enforces that var-refs are not linking to other variables. - pub fn resolve_fully(self, variables: &HashMap) -> Result { - self.into_iter() - .map(|element| match element { - AttrValElement::Primitive(x) => Ok(x), - AttrValElement::Expr(expr) => expr.eval(variables), - }) - .collect() - } - - // TODO this could be a fancy Iterator implementation, ig - pub fn parse_string(s: &str) -> AttrVal { - let mut elements = Vec::new(); - - let mut cur_word = "".to_owned(); - let mut cur_varref: Option = None; - let mut curly_count = 0; - for c in s.chars() { - if let Some(ref mut varref) = cur_varref { - if c == '}' { - curly_count -= 1; - if curly_count == 0 { - elements.push(AttrValElement::Expr(AttrValExpr::parse(varref).unwrap())); - cur_varref = None - } - } else { - curly_count = 2; - varref.push(c); - } - } else if c == '{' { - curly_count += 1; - if curly_count == 2 { - if !cur_word.is_empty() { - elements.push(AttrValElement::primitive(std::mem::take(&mut cur_word))); - } - cur_varref = Some(String::new()) - } - } else { - if curly_count == 1 { - cur_word.push('{'); - } - curly_count = 0; - cur_word.push(c); - } - } - if let Some(unfinished_varref) = cur_varref.take() { - elements.push(AttrValElement::primitive(unfinished_varref)); - } else if !cur_word.is_empty() { - elements.push(AttrValElement::primitive(cur_word)); - } - AttrVal(elements) - } -} - -#[derive(Clone, PartialEq, Serialize, Deserialize)] -pub enum AttrValElement { - Primitive(PrimVal), - Expr(AttrValExpr), -} -impl fmt::Display for AttrValElement { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - AttrValElement::Primitive(x) => write!(f, "{}", x), - AttrValElement::Expr(x) => write!(f, "{{{{{}}}}}", x), - } - } -} - -impl fmt::Debug for AttrValElement { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - AttrValElement::Primitive(x) => write!(f, "Primitive({:?})", x), - AttrValElement::Expr(x) => write!(f, "Expr({:?})", x), - } - } -} - -impl AttrValElement { - pub fn primitive(s: String) -> Self { - AttrValElement::Primitive(PrimVal::from_string(s)) - } - - pub fn as_expr(&self) -> Option<&AttrValExpr> { - match self { - AttrValElement::Expr(x) => Some(x), - _ => None, - } - } - - pub fn as_primitive(&self) -> Option<&PrimVal> { - match self { - AttrValElement::Primitive(x) => Some(x), - _ => None, - } - } -} - -#[cfg(test)] -mod test { - use super::*; - use pretty_assertions::assert_eq; - #[test] - fn test_parse_string_or_var_ref_list() { - let input = "{{foo}}{{bar}}b{}azb{a}z{{bat}}{}quok{{test}}"; - let output = AttrVal::parse_string(input); - assert_eq!( - output, - AttrVal(vec![ - AttrValElement::Expr(AttrValExpr::VarRef(VarName("foo".to_owned()))), - AttrValElement::Expr(AttrValExpr::VarRef(VarName("bar".to_owned()))), - AttrValElement::primitive("b{}azb{a}z".to_owned()), - AttrValElement::Expr(AttrValExpr::VarRef(VarName("bat".to_owned()))), - AttrValElement::primitive("{}quok".to_owned()), - AttrValElement::Expr(AttrValExpr::VarRef(VarName("test".to_owned()))), - ]), - ) - } - #[test] - fn test_parse_string_with_var_refs_attr_value() { - assert_eq!( - AttrVal( - vec![ - AttrValElement::Expr(AttrValExpr::VarRef(VarName("var".to_owned()))), - AttrValElement::primitive("something".to_owned()) - ] - .into() - ), - AttrVal::parse_string("{{var}}something") - ); - } -} diff --git a/crates/eww/src/value/attr_value/attr_value_expr.rs b/crates/eww/src/value/attr_value/attr_value_expr.rs deleted file mode 100644 index f565634..0000000 --- a/crates/eww/src/value/attr_value/attr_value_expr.rs +++ /dev/null @@ -1,244 +0,0 @@ -use super::super::*; -use anyhow::*; -use itertools::Itertools; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; - -#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)] -pub enum BinOp { - Plus, - Minus, - Times, - Div, - Mod, - Equals, - NotEquals, - And, - Or, - GT, - LT, - Elvis, - RegexMatch, -} - -impl std::fmt::Display for BinOp { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - BinOp::Plus => write!(f, "+"), - BinOp::Minus => write!(f, "-"), - BinOp::Times => write!(f, "*"), - BinOp::Div => write!(f, "/"), - BinOp::Mod => write!(f, "%"), - BinOp::Equals => write!(f, "=="), - BinOp::NotEquals => write!(f, "!="), - BinOp::And => write!(f, "&&"), - BinOp::Or => write!(f, "||"), - BinOp::GT => write!(f, ">"), - BinOp::LT => write!(f, "<"), - BinOp::Elvis => write!(f, "?:"), - BinOp::RegexMatch => write!(f, "=~"), - } - } -} - -#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)] -pub enum UnaryOp { - Not, -} - -impl std::fmt::Display for UnaryOp { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - UnaryOp::Not => write!(f, "!"), - } - } -} - -#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)] -pub enum AttrValExpr { - Literal(AttrVal), - VarRef(VarName), - BinOp(Box, BinOp, Box), - UnaryOp(UnaryOp, Box), - IfElse(Box, Box, Box), - JsonAccess(Box, Box), - FunctionCall(String, Vec), -} - -impl std::fmt::Display for AttrValExpr { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - AttrValExpr::VarRef(x) => write!(f, "{}", x), - AttrValExpr::Literal(x) => write!(f, "\"{}\"", x), - AttrValExpr::BinOp(l, op, r) => write!(f, "({} {} {})", l, op, r), - AttrValExpr::UnaryOp(op, x) => write!(f, "{}{}", op, x), - AttrValExpr::IfElse(a, b, c) => write!(f, "(if {} then {} else {})", a, b, c), - AttrValExpr::JsonAccess(value, index) => write!(f, "{}[{}]", value, index), - AttrValExpr::FunctionCall(function_name, args) => write!(f, "{}({})", function_name, args.iter().join(", ")), - } - } -} - -// impl std::fmt::Debug for AttrValueExpr { -// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { -// write!(f, "{:?}", self) -//} - -impl AttrValExpr { - pub fn map_terminals_into(self, f: impl Fn(Self) -> Self) -> Self { - use AttrValExpr::*; - match self { - BinOp(box a, op, box b) => BinOp(box f(a), op, box f(b)), - IfElse(box a, box b, box c) => IfElse(box f(a), box f(b), box f(c)), - other => f(other), - } - } - - /// resolve variable references in the expression. Fails if a variable cannot be resolved. - pub fn resolve_refs(self, variables: &HashMap) -> Result { - use AttrValExpr::*; - match self { - // Literal(x) => Ok(Literal(AttrValue::from_primitive(x.resolve_fully(&variables)?))), - Literal(x) => Ok(Literal(x)), - VarRef(ref name) => Ok(Literal(AttrVal::from_primitive( - variables.get(name).with_context(|| format!("Unknown variable {} referenced in {:?}", &name, &self))?.clone(), - ))), - BinOp(box a, op, box b) => Ok(BinOp(box a.resolve_refs(variables)?, op, box b.resolve_refs(variables)?)), - UnaryOp(op, box x) => Ok(UnaryOp(op, box x.resolve_refs(variables)?)), - IfElse(box a, box b, box c) => { - Ok(IfElse(box a.resolve_refs(variables)?, box b.resolve_refs(variables)?, box c.resolve_refs(variables)?)) - } - JsonAccess(box a, box b) => Ok(JsonAccess(box a.resolve_refs(variables)?, box b.resolve_refs(variables)?)), - FunctionCall(function_name, args) => { - Ok(FunctionCall(function_name, args.into_iter().map(|a| a.resolve_refs(variables)).collect::>()?)) - } - } - } - - pub fn var_refs(&self) -> Vec<&VarName> { - use AttrValExpr::*; - match self { - Literal(s) => s.var_refs().collect(), - VarRef(name) => vec![name], - BinOp(box a, _, box b) => { - let mut refs = a.var_refs(); - refs.append(&mut b.var_refs()); - refs - } - UnaryOp(_, box x) => x.var_refs(), - IfElse(box a, box b, box c) => { - let mut refs = a.var_refs(); - refs.append(&mut b.var_refs()); - refs.append(&mut c.var_refs()); - refs - } - JsonAccess(box a, box b) => { - let mut refs = a.var_refs(); - refs.append(&mut b.var_refs()); - refs - } - FunctionCall(_, args) => args.iter().flat_map(|a| a.var_refs()).collect_vec(), - } - } - - pub fn eval(self, values: &HashMap) -> Result { - match self { - AttrValExpr::Literal(x) => x.resolve_fully(values), - AttrValExpr::VarRef(ref name) => values - .get(name) - .cloned() - .context(format!("Got unresolved variable {} while trying to evaluate expression {:?}", &name, &self)), - AttrValExpr::BinOp(a, op, b) => { - let a = a.eval(values)?; - let b = b.eval(values)?; - Ok(match op { - BinOp::Equals => PrimVal::from(a == b), - BinOp::NotEquals => PrimVal::from(a != b), - BinOp::And => PrimVal::from(a.as_bool()? && b.as_bool()?), - BinOp::Or => PrimVal::from(a.as_bool()? || b.as_bool()?), - - BinOp::Plus => PrimVal::from(a.as_f64()? + b.as_f64()?), - BinOp::Minus => PrimVal::from(a.as_f64()? - b.as_f64()?), - BinOp::Times => PrimVal::from(a.as_f64()? * b.as_f64()?), - BinOp::Div => PrimVal::from(a.as_f64()? / b.as_f64()?), - BinOp::Mod => PrimVal::from(a.as_f64()? % b.as_f64()?), - BinOp::GT => PrimVal::from(a.as_f64()? > b.as_f64()?), - BinOp::LT => PrimVal::from(a.as_f64()? < b.as_f64()?), - BinOp::Elvis => PrimVal::from(if a.0.is_empty() { b } else { a }), - BinOp::RegexMatch => { - let regex = regex::Regex::new(&b.as_string()?)?; - PrimVal::from(regex.is_match(&a.as_string()?)) - } - }) - } - AttrValExpr::UnaryOp(op, a) => { - let a = a.eval(values)?; - Ok(match op { - UnaryOp::Not => PrimVal::from(!a.as_bool()?), - }) - } - AttrValExpr::IfElse(cond, yes, no) => { - if cond.eval(values)?.as_bool()? { - yes.eval(values) - } else { - no.eval(values) - } - } - AttrValExpr::JsonAccess(val, index) => { - let val = val.eval(values)?; - let index = index.eval(values)?; - match val.as_json_value()? { - serde_json::Value::Array(val) => { - let index = index.as_i32()?; - let indexed_value = val.get(index as usize).unwrap_or(&serde_json::Value::Null); - Ok(PrimVal::from(indexed_value)) - } - serde_json::Value::Object(val) => { - let indexed_value = val - .get(&index.as_string()?) - .or_else(|| val.get(&index.as_i32().ok()?.to_string())) - .unwrap_or(&serde_json::Value::Null); - Ok(PrimVal::from(indexed_value)) - } - _ => bail!("Unable to index into value {}", val), - } - } - AttrValExpr::FunctionCall(function_name, args) => { - let args = args.into_iter().map(|a| a.eval(values)).collect::>()?; - call_expr_function(&function_name, args) - } - } - } - - pub fn parse(s: &str) -> Result { - let parsed = match parser::parse(s) { - Ok((_, x)) => Ok(x), - Err(nom::Err::Error(e) | nom::Err::Failure(e)) => Err(anyhow!(nom::error::convert_error(s, e))), - Err(nom::Err::Incomplete(_)) => Err(anyhow!("Parsing incomplete")), - }; - parsed.context("Failed to parse expression") - } -} - -fn call_expr_function(name: &str, args: Vec) -> Result { - match name { - "round" => match args.as_slice() { - [num, digits] => { - let num = num.as_f64()?; - let digits = digits.as_i32()?; - Ok(PrimVal::from(format!("{:.1$}", num, digits as usize))) - } - _ => Err(anyhow!("Incorrect number of arguments given to {}", name)), - }, - "replace" => match args.as_slice() { - [string, pattern, replacement] => { - let string = string.as_string()?; - let pattern = regex::Regex::new(&pattern.as_string()?)?; - let replacement = replacement.as_string()?; - Ok(PrimVal::from(pattern.replace_all(&string, replacement.replace("$", "$$").replace("\\", "$")).into_owned())) - } - _ => Err(anyhow!("Incorrect number of arguments given to {}", name)), - }, - _ => Err(anyhow!("Unknown function {}", name)), - } -} diff --git a/crates/eww/src/value/attr_value/mod.rs b/crates/eww/src/value/attr_value/mod.rs deleted file mode 100644 index 077a689..0000000 --- a/crates/eww/src/value/attr_value/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod attr_value; -pub mod attr_value_expr; -pub mod parser; -pub use attr_value::*; -pub use attr_value_expr::*; diff --git a/crates/eww/src/value/attr_value/parser.rs b/crates/eww/src/value/attr_value/parser.rs deleted file mode 100644 index 5f73d1d..0000000 --- a/crates/eww/src/value/attr_value/parser.rs +++ /dev/null @@ -1,224 +0,0 @@ -use super::*; - -use nom::{ - branch::*, - bytes::complete::{tag, take_while}, - character::complete::{multispace0 as multispace, *}, - combinator::{map, map_res, *}, - error::{context, ParseError, VerboseError}, - multi::{many0, separated_list0}, - sequence::{delimited, preceded, *}, - IResult, Parser, -}; - -use super::super::*; - -fn ws<'a, P, O, E: ParseError<&'a str>>(p: P) -> impl FnMut(&'a str) -> IResult<&'a str, O, E> -where - P: Parser<&'a str, O, E>, -{ - delimited(multispace, p, multispace) -} - -fn parse_num(i: &str) -> IResult<&str, f64, VerboseError<&str>> { - let (i, neg) = opt(tag("-"))(i)?; - let (i, num): (_, f64) = map_res(take_while(|c: char| c.is_numeric() || c == '.'), |n: &str| n.parse::())(i)?; - Ok((i, if neg.is_some() { -num } else { num })) -} - -fn parse_bool(i: &str) -> IResult<&str, &str, VerboseError<&str>> { - alt((tag("true"), tag("false")))(i) -} - -fn parse_literal(i: &str) -> IResult<&str, &str, VerboseError<&str>> { - alt((parse_bool, parse_stringlit, recognize(parse_num)))(i) -} - -fn parse_stringlit(i: &str) -> IResult<&str, &str, VerboseError<&str>> { - alt((delimited(tag("'"), take_while(|c| c != '\''), tag("'")), delimited(tag("\""), take_while(|c| c != '"'), tag("\""))))(i) -} - -fn parse_identifier(i: &str) -> IResult<&str, &str, VerboseError<&str>> { - verify(recognize(pair(alt((alpha1, tag("_"), tag("-"))), many0(alt((alphanumeric1, tag("_"), tag("-")))))), |x| { - !["if", "then", "else"].contains(x) - })(i) -} - -fn parse_unary_op(i: &str) -> IResult<&str, UnaryOp, VerboseError<&str>> { - value(UnaryOp::Not, tag("!"))(i) -} - -fn parse_function_call(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { - let (i, name) = take_while(|c: char| c.is_ascii_alphanumeric() || c == '_')(i)?; - let (i, args) = delimited(tag("("), separated_list0(tag(","), ws(parse_expr)), tag(")"))(i)?; - Ok((i, AttrValExpr::FunctionCall(name.to_string(), args))) -} - -///////////////// -// actual tree // -///////////////// - -fn parse_factor(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { - let (i, unary_op) = opt(parse_unary_op)(i)?; - let (i, factor) = alt(( - context("expression", ws(delimited(tag("("), parse_expr, tag(")")))), - context("if-expression", ws(parse_ifelse)), - context("function-call", ws(parse_function_call)), - context("literal", map(ws(parse_literal), |x| AttrValExpr::Literal(AttrVal::parse_string(x)))), - context("identifier", map(ws(parse_identifier), |x| AttrValExpr::VarRef(VarName(x.to_string())))), - ))(i)?; - Ok(( - i, - match unary_op { - Some(op) => AttrValExpr::UnaryOp(op, box factor), - None => factor, - }, - )) -} - -fn parse_object_index(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { - let (i, initial) = parse_factor(i)?; - let (i, remainder) = many0(alt(( - delimited(tag("["), ws(parse_expr), tag("]")), - map(preceded(tag("."), parse_identifier), |x| AttrValExpr::Literal(AttrVal::from_primitive(x))), - )))(i)?; - let indexes = remainder.into_iter().fold(initial, |acc, index| AttrValExpr::JsonAccess(box acc, box index)); - Ok((i, indexes)) -} - -fn parse_term3(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { - let (i, initial) = parse_object_index(i)?; - let (i, remainder) = many0(alt(( - map(preceded(tag("*"), parse_object_index), |x| (BinOp::Times, x)), - map(preceded(tag("/"), parse_object_index), |x| (BinOp::Div, x)), - map(preceded(tag("%"), parse_object_index), |x| (BinOp::Mod, x)), - )))(i)?; - - let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValExpr::BinOp(box acc, op, box expr)); - - Ok((i, exprs)) -} -fn parse_term2(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { - let (i, initial) = parse_term3(i)?; - let (i, remainder) = many0(alt(( - map(preceded(tag("+"), parse_term3), |x| (BinOp::Plus, x)), - map(preceded(tag("-"), parse_term3), |x| (BinOp::Minus, x)), - )))(i)?; - - let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValExpr::BinOp(box acc, op, box expr)); - - Ok((i, exprs)) -} - -fn parse_term1(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { - let (i, initial) = parse_term2(i)?; - let (i, remainder) = many0(alt(( - map(preceded(tag("=="), parse_term2), |x| (BinOp::Equals, x)), - map(preceded(tag("!="), parse_term2), |x| (BinOp::NotEquals, x)), - map(preceded(tag(">"), parse_term2), |x| (BinOp::GT, x)), - map(preceded(tag("<"), parse_term2), |x| (BinOp::LT, x)), - map(preceded(tag("=~"), parse_term2), |x| (BinOp::RegexMatch, x)), - )))(i)?; - - let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValExpr::BinOp(box acc, op, box expr)); - - Ok((i, exprs)) -} -pub fn parse_expr(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { - let (i, initial) = parse_term1(i)?; - let (i, remainder) = many0(alt(( - map(preceded(tag("&&"), parse_term1), |x| (BinOp::And, x)), - map(preceded(tag("||"), parse_term1), |x| (BinOp::Or, x)), - map(preceded(tag("?:"), parse_term1), |x| (BinOp::Elvis, x)), - )))(i)?; - - let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValExpr::BinOp(box acc, op, box expr)); - - Ok((i, exprs)) -} - -fn parse_ifelse(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { - let (i, _) = tag("if")(i)?; - let (i, a) = context("condition", ws(parse_expr))(i)?; - let (i, _) = tag("then")(i)?; - let (i, b) = context("true-case", ws(parse_expr))(i)?; - let (i, _) = tag("else")(i)?; - let (i, c) = context("false-case", ws(parse_expr))(i)?; - Ok((i, AttrValExpr::IfElse(box a, box b, box c))) -} - -pub fn parse(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { - complete(parse_expr)(i) -} - -#[cfg(test)] -mod test { - use super::*; - use pretty_assertions::assert_eq; - #[test] - fn test_parser() { - use self::{BinOp::*, UnaryOp::*}; - use AttrValExpr::*; - - assert_eq!(("", 12.22f64), parse_num("12.22").unwrap()); - assert_eq!(Literal(AttrVal::from_primitive("12")), AttrValExpr::parse("12").unwrap()); - assert_eq!(UnaryOp(Not, box Literal(AttrVal::from_primitive("false"))), AttrValExpr::parse("!false").unwrap()); - assert_eq!( - BinOp(box Literal(AttrVal::from_primitive("12")), Plus, box Literal(AttrVal::from_primitive("2"))), - AttrValExpr::parse("12 + 2").unwrap() - ); - assert_eq!( - BinOp( - box FunctionCall( - "test".to_string(), - vec![ - JsonAccess(box VarRef(VarName("foo".to_string())), box Literal(AttrVal::from_primitive("hi"))), - Literal(AttrVal::from_primitive("ho")), - ] - ), - Times, - box Literal(AttrVal::from_primitive(2)) - ), - AttrValExpr::parse(r#"(test(foo["hi"], ("ho")) * 2)"#).unwrap() - ); - assert_eq!( - UnaryOp(Not, box BinOp(box Literal(AttrVal::from_primitive("1")), Equals, box Literal(AttrVal::from_primitive("2")))), - AttrValExpr::parse("!(1 == 2)").unwrap() - ); - assert_eq!( - IfElse( - box VarRef(VarName("a".to_string())), - box VarRef(VarName("b".to_string())), - box VarRef(VarName("c".to_string())), - ), - AttrValExpr::parse("if a then b else c").unwrap() - ); - assert_eq!( - JsonAccess( - box VarRef(VarName("array".to_string())), - box BinOp(box Literal(AttrVal::from_primitive("1")), Plus, box Literal(AttrVal::from_primitive("2"))) - ), - AttrValExpr::parse(r#"(array)[1+2]"#).unwrap() - ); - assert_eq!( - JsonAccess( - box JsonAccess( - box VarRef(VarName("object".to_string())), - box Literal(AttrVal::from_primitive("field".to_string())), - ), - box Literal(AttrVal::from_primitive("field2".to_string())), - ), - AttrValExpr::parse(r#"object.field.field2"#).unwrap() - ); - } - #[test] - fn test_complex() { - let parsed = - AttrValExpr::parse(r#"if hi > 12 + 2 * 2 && 12 == 15 then "foo" else if !true then 'hi' else "{{bruh}}""#).unwrap(); - - assert_eq!( - r#"(if ((hi > ("12" + ("2" * "2"))) && ("12" == "15")) then "foo" else (if !"true" then "hi" else "{{bruh}}"))"#, - format!("{}", parsed), - ) - } -} diff --git a/crates/eww/src/value/coords.rs b/crates/eww/src/value/coords.rs deleted file mode 100644 index cb50699..0000000 --- a/crates/eww/src/value/coords.rs +++ /dev/null @@ -1,107 +0,0 @@ -use anyhow::*; -use derive_more::*; -use serde::{Deserialize, Serialize}; -use smart_default::SmartDefault; -use std::{fmt, str::FromStr}; - -#[derive(Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Display, DebugCustom, SmartDefault)] -pub enum NumWithUnit { - #[display(fmt = "{}%", .0)] - #[debug(fmt = "{}%", .0)] - Percent(i32), - #[display(fmt = "{}px", .0)] - #[debug(fmt = "{}px", .0)] - #[default] - Pixels(i32), -} - -impl NumWithUnit { - pub fn relative_to(&self, max: i32) -> i32 { - match *self { - NumWithUnit::Percent(n) => ((max as f64 / 100.0) * n as f64) as i32, - NumWithUnit::Pixels(n) => n, - } - } -} - -impl FromStr for NumWithUnit { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - lazy_static::lazy_static! { - static ref PATTERN: regex::Regex = regex::Regex::new("^(-?\\d+)(.*)$").unwrap(); - }; - - let captures = PATTERN.captures(s).with_context(|| format!("could not parse '{}'", s))?; - let value = captures.get(1).unwrap().as_str().parse::()?; - let value = match captures.get(2).unwrap().as_str() { - "px" | "" => NumWithUnit::Pixels(value), - "%" => NumWithUnit::Percent(value), - _ => bail!("couldn't parse {}, unit must be either px or %", s), - }; - Ok(value) - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Display, Default)] -#[display(fmt = "{}*{}", x, y)] -pub struct Coords { - pub x: NumWithUnit, - pub y: NumWithUnit, -} - -impl FromStr for Coords { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - let (x, y) = s - .split_once(|x: char| x.to_ascii_lowercase() == 'x' || x.to_ascii_lowercase() == '*') - .ok_or_else(|| anyhow!("must be formatted like 200x500"))?; - Coords::from_strs(x, y) - } -} - -impl fmt::Debug for Coords { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "CoordsWithUnits({}, {})", self.x, self.y) - } -} - -impl Coords { - pub fn from_pixels(x: i32, y: i32) -> Self { - Coords { x: NumWithUnit::Pixels(x), y: NumWithUnit::Pixels(y) } - } - - /// parse a string for x and a string for y into a [`Coords`] object. - pub fn from_strs(x: &str, y: &str) -> Result { - Ok(Coords { - x: x.parse().with_context(|| format!("Failed to parse '{}'", x))?, - y: y.parse().with_context(|| format!("Failed to parse '{}'", y))?, - }) - } - - /// resolve the possibly relative coordinates relative to a given containers size - pub fn relative_to(&self, width: i32, height: i32) -> (i32, i32) { - (self.x.relative_to(width), self.y.relative_to(height)) - } -} - -#[cfg(test)] -mod test { - use super::*; - use pretty_assertions::assert_eq; - - #[test] - fn test_parse_num_with_unit() { - assert_eq!(NumWithUnit::Pixels(55), NumWithUnit::from_str("55").unwrap()); - assert_eq!(NumWithUnit::Pixels(55), NumWithUnit::from_str("55px").unwrap()); - assert_eq!(NumWithUnit::Percent(55), NumWithUnit::from_str("55%").unwrap()); - assert!(NumWithUnit::from_str("55pp").is_err()); - } - - #[test] - fn test_parse_coords() { - assert_eq!(Coords { x: NumWithUnit::Pixels(50), y: NumWithUnit::Pixels(60) }, Coords::from_str("50x60").unwrap()); - assert!(Coords::from_str("5060").is_err()); - } -} diff --git a/crates/eww/src/value/mod.rs b/crates/eww/src/value/mod.rs deleted file mode 100644 index cd002af..0000000 --- a/crates/eww/src/value/mod.rs +++ /dev/null @@ -1,46 +0,0 @@ -use derive_more::*; -use serde::{Deserialize, Serialize}; - -pub mod attr_value; -pub mod coords; -pub mod primitive; -pub use attr_value::*; -pub use attr_value_expr::*; -pub use coords::*; -pub use primitive::*; - -/// The name of a variable -#[repr(transparent)] -#[derive(Clone, Hash, PartialEq, Eq, Serialize, Deserialize, AsRef, From, FromStr, Display, DebugCustom)] -#[debug(fmt = "VarName({})", .0)] -pub struct VarName(pub String); - -impl std::borrow::Borrow for VarName { - fn borrow(&self) -> &str { - &self.0 - } -} - -impl From<&str> for VarName { - fn from(s: &str) -> Self { - VarName(s.to_owned()) - } -} - -/// The name of an attribute -#[repr(transparent)] -#[derive(Clone, Hash, PartialEq, Eq, Serialize, Deserialize, AsRef, From, FromStr, Display, DebugCustom)] -#[debug(fmt="AttrName({})", .0)] -pub struct AttrName(pub String); - -impl std::borrow::Borrow for AttrName { - fn borrow(&self) -> &str { - &self.0 - } -} - -impl From<&str> for AttrName { - fn from(s: &str) -> Self { - AttrName(s.to_owned()) - } -} diff --git a/crates/eww/src/value/primitive.rs b/crates/eww/src/value/primitive.rs deleted file mode 100644 index 98a771c..0000000 --- a/crates/eww/src/value/primitive.rs +++ /dev/null @@ -1,188 +0,0 @@ -use anyhow::*; -use itertools::Itertools; -use serde::{Deserialize, Serialize}; -use std::{convert::TryFrom, fmt, iter::FromIterator}; - -use crate::impl_try_from; - -#[derive(Clone, Deserialize, Serialize, derive_more::From, Default)] -pub struct PrimVal(pub String); - -impl fmt::Display for PrimVal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) - } -} -impl fmt::Debug for PrimVal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "\"{}\"", self.0) - } -} - -/// Manually implement equality, to allow for values in different formats (i.e. "1" and "1.0") to still be considered as equal. -impl std::cmp::PartialEq for PrimVal { - fn eq(&self, other: &Self) -> bool { - if let (Ok(a), Ok(b)) = (self.as_f64(), other.as_f64()) { - a == b - } else { - self.0 == other.0 - } - } -} - -impl FromIterator for PrimVal { - fn from_iter>(iter: T) -> Self { - PrimVal(iter.into_iter().join("")) - } -} - -impl std::str::FromStr for PrimVal { - type Err = anyhow::Error; - - /// parses the value, trying to turn it into a number and a boolean first, - /// before deciding that it is a string. - fn from_str(s: &str) -> Result { - Ok(PrimVal::from_string(s.to_string())) - } -} - -impl_try_from!(PrimVal { - for String => |x| x.as_string(); - for f64 => |x| x.as_f64(); - for bool => |x| x.as_bool(); - for Vec => |x| x.as_vec(); -}); - -impl From for PrimVal { - fn from(x: bool) -> Self { - PrimVal(x.to_string()) - } -} - -impl From for PrimVal { - fn from(s: i32) -> Self { - PrimVal(s.to_string()) - } -} - -impl From for PrimVal { - fn from(s: u32) -> Self { - PrimVal(s.to_string()) - } -} - -impl From for PrimVal { - fn from(s: f32) -> Self { - PrimVal(s.to_string()) - } -} - -impl From for PrimVal { - fn from(s: u8) -> Self { - PrimVal(s.to_string()) - } -} -impl From for PrimVal { - fn from(s: f64) -> Self { - PrimVal(s.to_string()) - } -} - -impl From<&str> for PrimVal { - fn from(s: &str) -> Self { - PrimVal(s.to_string()) - } -} - -impl From<&serde_json::Value> for PrimVal { - fn from(v: &serde_json::Value) -> Self { - PrimVal( - v.as_str() - .map(|x| x.to_string()) - .or_else(|| serde_json::to_string(v).ok()) - .unwrap_or_else(|| "".to_string()), - ) - } -} - -impl PrimVal { - pub fn from_string(s: String) -> Self { - PrimVal(s) - } - - pub fn into_inner(self) -> String { - self.0 - } - - /// This will never fail - pub fn as_string(&self) -> Result { - Ok(self.0.to_owned()) - } - - pub fn as_f64(&self) -> Result { - self.0.parse().map_err(|e| anyhow!("couldn't convert {:?} to f64: {}", &self, e)) - } - - pub fn as_i32(&self) -> Result { - self.0.parse().map_err(|e| anyhow!("couldn't convert {:?} to i32: {}", &self, e)) - } - - pub fn as_bool(&self) -> Result { - self.0.parse().map_err(|e| anyhow!("couldn't convert {:?} to bool: {}", &self, e)) - } - - pub fn as_vec(&self) -> Result> { - parse_vec(self.0.to_owned()).map_err(|e| anyhow!("Couldn't convert {:#?} to a vec: {}", &self, e)) - } - - pub fn as_json_value(&self) -> Result { - serde_json::from_str::(&self.0) - .with_context(|| format!("Couldn't convert {:#?} to a json object", &self)) - } -} - -fn parse_vec(a: String) -> Result> { - match a.strip_prefix('[').and_then(|x| x.strip_suffix(']')) { - Some(content) => { - let mut items: Vec = content.split(',').map(|x: &str| x.to_string()).collect(); - let mut removed = 0; - for times_ran in 0..items.len() { - // escapes `,` if there's a `\` before em - if items[times_ran - removed].ends_with('\\') { - items[times_ran - removed].pop(); - let it = items.remove((times_ran + 1) - removed); - items[times_ran - removed] += ","; - items[times_ran - removed] += ⁢ - removed += 1; - } - } - Ok(items) - } - None => Err(anyhow!("Is your array built like this: '[these,are,items]'?")), - } -} - -#[cfg(test)] -mod test { - use super::*; - use pretty_assertions::assert_eq; - #[test] - fn test_parse_vec() { - assert_eq!(vec![""], parse_vec("[]".to_string()).unwrap(), "should be able to parse empty lists"); - assert_eq!(vec!["hi"], parse_vec("[hi]".to_string()).unwrap(), "should be able to parse single element list"); - assert_eq!( - vec!["hi", "ho", "hu"], - parse_vec("[hi,ho,hu]".to_string()).unwrap(), - "should be able to parse three element list" - ); - assert_eq!(vec!["hi,ho"], parse_vec("[hi\\,ho]".to_string()).unwrap(), "should be able to parse list with escaped comma"); - assert_eq!( - vec!["hi,ho", "hu"], - parse_vec("[hi\\,ho,hu]".to_string()).unwrap(), - "should be able to parse two element list with escaped comma" - ); - assert!(parse_vec("".to_string()).is_err(), "Should fail when parsing empty string"); - assert!(parse_vec("[a,b".to_string()).is_err(), "Should fail when parsing unclosed list"); - assert!(parse_vec("a]".to_string()).is_err(), "Should fail when parsing unopened list"); - } -} diff --git a/crates/eww/src/widgets/mod.rs b/crates/eww/src/widgets/mod.rs index c6214ae..d772fdc 100644 --- a/crates/eww/src/widgets/mod.rs +++ b/crates/eww/src/widgets/mod.rs @@ -1,12 +1,12 @@ use crate::{ config::{element::WidgetDefinition, window_definition::WindowName}, eww_state::*, - value::AttrName, }; use anyhow::*; use gtk::prelude::*; use itertools::Itertools; use std::collections::HashMap; +use yuck::value::AttrName; use std::process::Command; use widget_definitions::*; @@ -132,7 +132,7 @@ macro_rules! resolve_block { let attr_map: Result<_> = try { ::maplit::hashmap! { $( - crate::value::AttrName(::std::stringify!($attr_name).to_owned()) => + yuck::value::AttrName(::std::stringify!($attr_name).to_owned()) => resolve_block!(@get_value $args, &::std::stringify!($attr_name).replace('_', "-"), $(= $default)?) ),* } @@ -154,7 +154,7 @@ macro_rules! resolve_block { }; (@get_value $args:ident, $name:expr, = $default:expr) => { - $args.widget.get_attr($name).cloned().unwrap_or(AttrVal::from_primitive($default)) + $args.widget.get_attr($name).cloned().unwrap_or(simplexpr::SimplExpr::synth_literal($default)) }; (@get_value $args:ident, $name:expr,) => { diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs index d806092..2f69689 100644 --- a/crates/eww/src/widgets/widget_definitions.rs +++ b/crates/eww/src/widgets/widget_definitions.rs @@ -3,7 +3,6 @@ use super::{run_command, BuilderArgs}; use crate::{ config, enum_parse, eww_state, resolve_block, util::{list_difference, parse_duration}, - value::AttrVal, widgets::widget_node, }; use anyhow::*; diff --git a/crates/eww/src/widgets/widget_node.rs b/crates/eww/src/widgets/widget_node.rs index bb7171b..c05a80a 100644 --- a/crates/eww/src/widgets/widget_node.rs +++ b/crates/eww/src/widgets/widget_node.rs @@ -5,7 +5,7 @@ use crate::{ WindowName, }, eww_state::EwwState, - value::{AttrName, AttrVal, VarName}, + dynval::{AttrName, AttrVal, VarName}, }; use anyhow::*; use dyn_clone; diff --git a/crates/simplexpr/src/ast.rs b/crates/simplexpr/src/ast.rs index 519b0d3..db1aaf9 100644 --- a/crates/simplexpr/src/ast.rs +++ b/crates/simplexpr/src/ast.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; /// stores the left and right end of a span, and a given file identifier. #[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize)] pub struct Span(pub usize, pub usize, pub usize); +pub static DUMMY_SPAN: Span = Span(usize::MAX, usize::MAX, usize::MAX); impl std::fmt::Display for Span { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -73,6 +74,11 @@ impl SimplExpr { Self::Literal(span, DynVal(s, Some(span))) } + /// Construct a synthetic simplexpr from a literal value, without adding any relevant span information (uses [DUMMY_SPAN]) + pub fn synth_literal(s: String) -> Self { + Self::Literal(DUMMY_SPAN, DynVal(s, Some(DUMMY_SPAN))) + } + pub fn span(&self) -> Span { match self { SimplExpr::Literal(span, _) => *span, diff --git a/crates/simplexpr/src/dynval.rs b/crates/simplexpr/src/dynval.rs index 2ee7c5a..e9685f0 100644 --- a/crates/simplexpr/src/dynval.rs +++ b/crates/simplexpr/src/dynval.rs @@ -10,11 +10,11 @@ pub type Result = std::result::Result; pub struct ConversionError { pub value: DynVal, pub target_type: &'static str, - pub source: Option>, + pub source: Option>, } impl ConversionError { - fn new(value: DynVal, target_type: &'static str, source: impl std::error::Error + 'static) -> Self { + fn new(value: DynVal, target_type: &'static str, source: impl std::error::Error + 'static + Sync + Send) -> Self { ConversionError { value, target_type, source: Some(Box::new(source)) } } diff --git a/crates/simplexpr/src/error.rs b/crates/simplexpr/src/error.rs index 74e193f..187f18d 100644 --- a/crates/simplexpr/src/error.rs +++ b/crates/simplexpr/src/error.rs @@ -14,13 +14,13 @@ pub enum Error { ConversionError(#[from] dynval::ConversionError), #[error("{1}")] - Spanned(Span, Box), + Spanned(Span, Box), #[error(transparent)] Eval(#[from] crate::eval::EvalError), #[error(transparent)] - Other(#[from] Box), + Other(#[from] Box), } impl Error { diff --git a/crates/yuck/Cargo.toml b/crates/yuck/Cargo.toml index b5ab428..c0031dd 100644 --- a/crates/yuck/Cargo.toml +++ b/crates/yuck/Cargo.toml @@ -23,6 +23,7 @@ pretty_assertions = "0.7" strum = { version = "0.21", features = ["derive"] } anyhow = "1" +static_assertions = "1.1" simplexpr = { path = "../simplexpr" } diff --git a/crates/yuck/examples/validation.rs b/crates/yuck/examples/validation.rs index f2cca38..d2c739d 100644 --- a/crates/yuck/examples/validation.rs +++ b/crates/yuck/examples/validation.rs @@ -1,4 +1,4 @@ -use eww_config::{ +use yuck::{ config::{widget_definition::WidgetDefinition, widget_use::WidgetUse, *}, error::AstError, format_diagnostic::ToDiagnostic, @@ -19,8 +19,8 @@ fn main() { let file_id_use = files.add("use.eww", input_use); let file_id_def = files.add("def.eww", input_def); - let parsed_use = WidgetUse::from_ast(eww_config::parser::parse_string(file_id_use, input_use).unwrap()).unwrap(); - let parsed_def = WidgetDefinition::from_ast(eww_config::parser::parse_string(file_id_def, input_def).unwrap()).unwrap(); + let parsed_use = WidgetUse::from_ast(yuck::parser::parse_string(file_id_use, input_use).unwrap()).unwrap(); + let parsed_def = WidgetDefinition::from_ast(yuck::parser::parse_string(file_id_def, input_def).unwrap()).unwrap(); let defs = maplit::hashmap! { "foo".to_string() => parsed_def, }; diff --git a/crates/yuck/src/config/attributes.rs b/crates/yuck/src/config/attributes.rs index b2e668d..34afc6b 100644 --- a/crates/yuck/src/config/attributes.rs +++ b/crates/yuck/src/config/attributes.rs @@ -27,7 +27,7 @@ pub enum AttrError { EvaluationError(Span, EvalError), #[error("{1}")] - Other(Span, Box), + Other(Span, Box), } impl AttrError { @@ -86,7 +86,7 @@ impl Attributes { pub fn primitive_required(&mut self, key: &str) -> Result where - E: std::error::Error + 'static, + E: std::error::Error + 'static + Sync + Send, T: FromDynVal, { let ast: SimplExpr = self.ast_required(&key)?; @@ -99,7 +99,7 @@ impl Attributes { pub fn primitive_optional(&mut self, key: &str) -> Result, AstError> where - E: std::error::Error + 'static, + E: std::error::Error + 'static + Sync + Send, T: FromDynVal, { let ast: SimplExpr = match self.ast_optional(key)? { diff --git a/crates/yuck/src/config/config.rs b/crates/yuck/src/config/config.rs index b969b4f..710e717 100644 --- a/crates/yuck/src/config/config.rs +++ b/crates/yuck/src/config/config.rs @@ -46,10 +46,10 @@ impl FromAst for TopLevel { #[derive(Debug, PartialEq, Eq, Clone, serde::Serialize)] pub struct Config { - widget_definitions: HashMap, - window_definitions: HashMap, - var_definitions: HashMap, - script_vars: HashMap, + pub widget_definitions: HashMap, + pub window_definitions: HashMap, + pub var_definitions: HashMap, + pub script_vars: HashMap, } impl FromAst for Config { diff --git a/crates/yuck/src/config/mod.rs b/crates/yuck/src/config/mod.rs index 2b3a558..3338d5d 100644 --- a/crates/yuck/src/config/mod.rs +++ b/crates/yuck/src/config/mod.rs @@ -1,6 +1,6 @@ pub mod attributes; pub mod backend_window_options; -mod config; +pub mod config; pub mod config_parse_error; pub mod script_var_definition; #[cfg(test)] @@ -11,3 +11,5 @@ pub mod widget_definition; pub mod widget_use; pub mod window_definition; pub mod window_geometry; + +pub use config::*; diff --git a/crates/yuck/src/config/script_var_definition.rs b/crates/yuck/src/config/script_var_definition.rs index 2d12424..5940a93 100644 --- a/crates/yuck/src/config/script_var_definition.rs +++ b/crates/yuck/src/config/script_var_definition.rs @@ -32,7 +32,7 @@ pub enum VarSource { // TODO allow for other executors? (python, etc) Shell(String), #[serde(skip)] - Function(fn() -> Result>), + Function(fn() -> Result>), } #[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)] pub struct PollScriptVar { diff --git a/crates/yuck/src/error.rs b/crates/yuck/src/error.rs index ac99e07..846a5d0 100644 --- a/crates/yuck/src/error.rs +++ b/crates/yuck/src/error.rs @@ -28,7 +28,7 @@ pub enum AstError { ConversionError(#[from] dynval::ConversionError), #[error("{1}")] - Other(Option, Box), + Other(Option, Box), #[error(transparent)] AttrError(#[from] AttrError), @@ -40,6 +40,10 @@ pub enum AstError { ParseError { file_id: Option, source: lalrpop_util::ParseError }, } +// static_assertions::assert_impl_all!(AstError: Send, Sync); +// static_assertions::assert_impl_all!(dynval::ConversionError: Send, Sync); +// static_assertions::assert_impl_all!(lalrpop_util::ParseError < usize, lexer::Token, parse_error::ParseError>: Send, Sync); + impl AstError { pub fn get_span(&self) -> Option { match self {