diff --git a/.gitignore b/.gitignore index 1c54c9b7..61d988af 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ build/* !build/Dockerfile.* .misc .direnv +callgrind.* +tracing.* diff --git a/Cargo.lock b/Cargo.lock index e233b251..5d4a7dc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,6 +216,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "atomic" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" +dependencies = [ + "bytemuck", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -249,6 +258,12 @@ dependencies = [ "windows-link", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "better-panic" version = "0.3.0" @@ -259,15 +274,30 @@ dependencies = [ "console", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec 0.6.3", +] + [[package]] name = "bit-set" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "bit-vec", + "bit-vec 0.8.0", ] +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bit-vec" version = "0.8.0" @@ -286,6 +316,15 @@ version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "block2" version = "0.5.1" @@ -404,12 +443,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6c0e7b807d60291f42f33f58480c0bfafe28ed08286446f45e463728cf9c1c" -[[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" - [[package]] name = "castaway" version = "0.2.4" @@ -517,9 +550,9 @@ dependencies = [ [[package]] name = "compact_str" -version = "0.8.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd622ebbb56a5b2ccb651b32b911cdeb2a9b4b11776b2473bf26a26a286244e" +checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab" dependencies = [ "castaway", "cfg-if", @@ -556,22 +589,9 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652" dependencies = [ - "const_panic_proc_macros", "typewit", ] -[[package]] -name = "const_panic_proc_macros" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb0240417fe20ccf13397fa25e6f0a987dbbfaf27d9e13532419df7f593e65e8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", - "unicode-xid", -] - [[package]] name = "convert_case" version = "0.10.0" @@ -621,6 +641,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -630,6 +659,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crossbeam-channel" version = "0.5.16" @@ -664,22 +699,6 @@ version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" -[[package]] -name = "crossterm" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" -dependencies = [ - "bitflags 2.13.1", - "crossterm_winapi", - "mio", - "parking_lot 0.12.5", - "rustix 0.38.44", - "signal-hook", - "signal-hook-mio", - "winapi", -] - [[package]] name = "crossterm" version = "0.29.0" @@ -707,6 +726,26 @@ dependencies = [ "winapi", ] +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "csscolorparser" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf" +dependencies = [ + "lab", + "phf 0.11.3", +] + [[package]] name = "cursor-icon" version = "1.2.0" @@ -747,6 +786,18 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "deltae" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4" + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" + [[package]] name = "derive_more" version = "2.1.1" @@ -769,6 +820,16 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -800,12 +861,13 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" name = "dizzle" version = "0.1.0" dependencies = [ - "const_panic", "dizzle_proc", - "itertools 0.14.0", - "konst", - "peg", + "itertools", + "profiling", "thiserror 2.0.19", + "tracing", + "tracing-flame", + "tracing-subscriber", ] [[package]] @@ -884,12 +946,31 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "euclid" +version = "0.22.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" +dependencies = [ + "num-traits", +] + [[package]] name = "extended" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365" +[[package]] +name = "fancy-regex" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +dependencies = [ + "bit-set 0.5.3", + "regex", +] + [[package]] name = "fastrand" version = "2.5.0" @@ -915,12 +996,35 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "filedescriptor" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d" +dependencies = [ + "libc", + "thiserror 1.0.69", + "winapi", +] + [[package]] name = "find-msvc-tools" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +[[package]] +name = "finl_unicode" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9844ddc3a6e533d62bba727eb6c28b5d360921d5175e9ff0f1e621a5c590a4d5" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.1.9" @@ -939,9 +1043,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "foreign-types" @@ -1125,6 +1229,16 @@ dependencies = [ "system-deps", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "gethostname" version = "1.1.0" @@ -1319,9 +1433,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", @@ -1333,6 +1447,11 @@ name = "hashbrown" version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] [[package]] name = "hdrhistogram" @@ -1362,6 +1481,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hotpath" version = "0.23.2" @@ -1515,15 +1640,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.14.0" @@ -1641,6 +1757,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kasuari" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde5057d6143cc94e861d90f591b9303d6716c6b9602309150bd068853c10899" +dependencies = [ + "hashbrown 0.16.1", + "portable-atomic", + "thiserror 2.0.19", +] + [[package]] name = "konst" version = "0.3.17" @@ -1688,6 +1815,12 @@ dependencies = [ "libc", ] +[[package]] +name = "lab" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f" + [[package]] name = "lazy_static" version = "1.5.0" @@ -1710,6 +1843,12 @@ dependencies = [ "windows-link", ] +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + [[package]] name = "libredox" version = "0.1.19" @@ -1743,6 +1882,15 @@ dependencies = [ "lv2_raw", ] +[[package]] +name = "line-clipping" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e752191d037c44ad111a8caa762921926658402f01cc1253f7bef2020ece4f5e" +dependencies = [ + "bitflags 2.13.1", +] + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -1791,11 +1939,11 @@ checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "lru" -version = "0.12.5" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "5d2f2f9b4ba7e6b24d95e7e899329d35be83bcded72c8540cdd5368932d1d90a" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.17.1", ] [[package]] @@ -1813,6 +1961,16 @@ dependencies = [ "libc", ] +[[package]] +name = "mac_address" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0aeb26bf5e836cc1c341c8106051b573f1766dfa05aa87f0b98be5e51b02303" +dependencies = [ + "nix", + "winapi", +] + [[package]] name = "memchr" version = "2.8.3" @@ -1828,6 +1986,12 @@ dependencies = [ "libc", ] +[[package]] +name = "memmem" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15" + [[package]] name = "memoffset" version = "0.9.1" @@ -1846,6 +2010,12 @@ dependencies = [ "rayon", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -1898,6 +2068,29 @@ dependencies = [ "jni-sys 0.3.1", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.13.1", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "notify" version = "8.2.0" @@ -1938,6 +2131,32 @@ dependencies = [ "bitflags 2.13.1", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1969,6 +2188,15 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "objc-sys" version = "0.3.5" @@ -2212,6 +2440,15 @@ dependencies = [ "libredox", ] +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + [[package]] name = "owned_ttf_parser" version = "0.25.1" @@ -2228,9 +2465,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddeed8580d347d2abf3dcf06a5f0b3dc020258338526b277847cd4248a70fc64" dependencies = [ "approx", + "libm", "palette_derive", "palette_math", - "phf", + "phf 0.13.1", "rand 0.8.7", ] @@ -2251,6 +2489,9 @@ name = "palette_math" version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e6eb142958d64335fb0e345c5b9ead2ecd6fc438c307e9d7d3c4fd428dbaf12" +dependencies = [ + "libm", +] [[package]] name = "pango" @@ -2331,46 +2572,113 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "peg" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aad070be5b63aa72103f2fcdd70a83adbd5e90112ce5b574171ff1c65501773" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd8ef6825cae95355031ae26a99b616a2a21f22ba2de0197c43dfb05acbe7ee" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7011d97b484a5ebdc4b1fdb3b12d5e4bbbea56e9d22b688f2e79e04b65a7d8a6" - [[package]] name = "percent-encoding" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pest" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a07a60cc7a4d00c91f95c685609d1d2f79050e6804b70ebedd7650f0b839bcf" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a83744a5c8455b8b3e0dc5031362780a347c878bdd11584d1a8984228cc88d" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd3451aa3de60d4b9a1e736885e4dea6b31617598026f12256ad566d63304a" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pest_meta" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04d3a0849e241d7dfce834c83b1c5edc8622009e8dd51a12ba1927c32f05496" +dependencies = [ + "pest", +] + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros", + "phf_shared 0.11.3", +] + [[package]] name = "phf" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "phf_shared", + "phf_shared 0.13.1", +] + +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.7", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", ] [[package]] @@ -2434,6 +2742,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -2518,14 +2838,34 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" +dependencies = [ + "profiling-procmacros", + "tracing", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" +dependencies = [ + "quote", + "syn 2.0.119", +] + [[package]] name = "proptest" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ - "bit-set", - "bit-vec", + "bit-set 0.8.0", + "bit-vec 0.8.0", "bitflags 2.13.1", "num-traits", "rand 0.9.5", @@ -2669,25 +3009,105 @@ dependencies = [ [[package]] name = "ratatui" -version = "0.29.0" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" +checksum = "3274ba0a2c5e1bcad2a2005d20f4dc59dad26b2eb0940fb094500dba4099d57d" +dependencies = [ + "instability", + "ratatui-core", + "ratatui-crossterm", + "ratatui-macros", + "ratatui-termina", + "ratatui-termwiz", + "ratatui-widgets", + "serde", +] + +[[package]] +name = "ratatui-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbb175c433c8e28a809d1f5773a2ae96e68c0ce40db865cbab1020bf33ae479c" dependencies = [ "bitflags 2.13.1", - "cassowary", "compact_str", - "crossterm 0.28.1", - "indoc", - "instability", - "itertools 0.13.0", + "critical-section", + "hashbrown 0.17.1", + "itertools", + "kasuari", "lru", - "paste", + "palette", + "serde", "strum", + "thiserror 2.0.19", "unicode-segmentation", "unicode-truncate", "unicode-width 0.2.0", ] +[[package]] +name = "ratatui-crossterm" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567584a3b0e6a8203c23de40b4861497266725eb5363dbfd18a1edd603cca9f0" +dependencies = [ + "cfg-if", + "crossterm", + "instability", + "ratatui-core", +] + +[[package]] +name = "ratatui-macros" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7dc68daa7498a43e4d68e0eb078427e10c38fbcfbb1e42d955f1fa2140d814" +dependencies = [ + "ratatui-core", + "ratatui-widgets", +] + +[[package]] +name = "ratatui-termina" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0bf912d9e66f057a759d92e386a280ea886b352ab757d6ac4d653c7ed2c43c2" +dependencies = [ + "instability", + "ratatui-core", + "termina", +] + +[[package]] +name = "ratatui-termwiz" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf03e0380b7744054d6cb74224fe3adf062a029754933f575ca1e3b4c2ce977" +dependencies = [ + "ratatui-core", + "termwiz", +] + +[[package]] +name = "ratatui-widgets" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66e3d19bcc9130ca376277d93b60767ff121ace3be06f5f95f81dd68956407d1" +dependencies = [ + "bitflags 2.13.1", + "hashbrown 0.17.1", + "indoc", + "instability", + "itertools", + "line-clipping", + "ratatui-core", + "serde", + "strum", + "time", + "unicode-segmentation", + "unicode-width 0.2.0", +] + [[package]] name = "raw-cpuid" version = "11.6.0" @@ -2974,6 +3394,26 @@ dependencies = [ "serde_core", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "2.0.1" @@ -3105,23 +3545,22 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.26.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.26.4" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "rustversion", "syn 2.0.119", ] @@ -3433,9 +3872,10 @@ dependencies = [ "anyhow", "atomic_float", "better-panic", - "crossterm 0.29.0", + "crossterm", "dizzle", "jack", + "konst", "midly", "palette", "quanta", @@ -3455,6 +3895,82 @@ dependencies = [ "winapi", ] +[[package]] +name = "termina" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9048a889effe34a5cddee0af7f53285198b16dca3be510858d38dfdb3e62a04e" +dependencies = [ + "bitflags 2.13.1", + "parking_lot 0.12.5", + "rustix 1.1.4", + "signal-hook", + "windows-sys 0.60.2", +] + +[[package]] +name = "terminfo" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662" +dependencies = [ + "fnv", + "nom", + "phf 0.11.3", + "phf_codegen", +] + +[[package]] +name = "termios" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b" +dependencies = [ + "libc", +] + +[[package]] +name = "termwiz" +version = "0.23.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7" +dependencies = [ + "anyhow", + "base64", + "bitflags 2.13.1", + "fancy-regex", + "filedescriptor", + "finl_unicode", + "fixedbitset", + "hex", + "lazy_static", + "libc", + "log", + "memmem", + "nix", + "num-derive", + "num-traits", + "ordered-float", + "pest", + "pest_derive", + "phf 0.11.3", + "sha2", + "signal-hook", + "siphasher", + "terminfo", + "termios", + "thiserror 1.0.69", + "ucd-trie", + "unicode-segmentation", + "vtparse", + "wezterm-bidi", + "wezterm-blob-leases", + "wezterm-color-types", + "wezterm-dynamic", + "wezterm-input-types", + "winapi", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -3495,6 +4011,36 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "thread_local" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde_core", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + [[package]] name = "tiny-skia" version = "0.11.4" @@ -3653,14 +4199,66 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "tracing-core" version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-flame" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bae117ee14789185e129aaee5d93750abe67fdc5a9a62650452bfe4e122a3a9" +dependencies = [ + "lazy_static", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] [[package]] name = "ttf-parser" @@ -3668,6 +4266,12 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + [[package]] name = "typewit" version = "1.15.2" @@ -3683,6 +4287,12 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "unarray" version = "0.1.4" @@ -3703,13 +4313,13 @@ checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-truncate" -version = "1.1.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" +checksum = "16b380a1238663e5f8a691f9039c73e1cdae598a30e9855f541d29b08b53e9a5" dependencies = [ - "itertools 0.13.0", + "itertools", "unicode-segmentation", - "unicode-width 0.1.14", + "unicode-width 0.2.0", ] [[package]] @@ -3724,12 +4334,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "utf8parse" version = "0.2.2" @@ -3742,11 +4346,18 @@ version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" dependencies = [ + "atomic", "getrandom 0.4.3", "js-sys", "wasm-bindgen", ] +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "version-compare" version = "0.2.1" @@ -3759,6 +4370,15 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vtparse" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9b2acfb050df409c972a37d3b8e08cdea3bddb0c09db9d53137e504cfabed0" +dependencies = [ + "utf8parse", +] + [[package]] name = "wait-timeout" version = "0.2.1" @@ -3990,6 +4610,78 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "wezterm-bidi" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0a6e355560527dd2d1cf7890652f4f09bb3433b6aadade4c9b5ed76de5f3ec" +dependencies = [ + "log", + "wezterm-dynamic", +] + +[[package]] +name = "wezterm-blob-leases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7" +dependencies = [ + "getrandom 0.3.4", + "mac_address", + "sha2", + "thiserror 1.0.69", + "uuid", +] + +[[package]] +name = "wezterm-color-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de81ef35c9010270d63772bebef2f2d6d1f2d20a983d27505ac850b8c4b4296" +dependencies = [ + "csscolorparser", + "deltae", + "lazy_static", + "wezterm-dynamic", +] + +[[package]] +name = "wezterm-dynamic" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f2ab60e120fd6eaa68d9567f3226e876684639d22a4219b313ff69ec0ccd5ac" +dependencies = [ + "log", + "ordered-float", + "strsim", + "thiserror 1.0.69", + "wezterm-dynamic-derive", +] + +[[package]] +name = "wezterm-dynamic-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c0cf2d539c645b448eaffec9ec494b8b19bd5077d9e58cb1ae7efece8d575b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "wezterm-input-types" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7012add459f951456ec9d6c7e6fc340b1ce15d6fc9629f8c42853412c029e57e" +dependencies = [ + "bitflags 1.3.2", + "euclid", + "lazy_static", + "serde", + "wezterm-dynamic", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Justfile b/Justfile index 87637b33..1c6633f7 100644 --- a/Justfile +++ b/Justfile @@ -1,5 +1,6 @@ #export RUSTFLAGS := "--cfg procmacro2_semver_exempt -Zmacro-backtrace -Clink-arg=-fuse-ld=mold" export RUST_BACKTRACE := "1" +export RUSTFLAGS := "-Zmacro-backtrace -Clink-arg=-fuse-ld=mold" [default] list: diff --git a/proc/src/lib.rs b/proc/src/lib.rs index bb971c63..21697811 100644 --- a/proc/src/lib.rs +++ b/proc/src/lib.rs @@ -233,7 +233,7 @@ attribute!(commands { append(disp, quote! { #command::#variant { #params } => state.#ident(#params), }); append(exps, quote! { let tail_base = tail; - if head.src()? == Some(#keyword) { + if head == Some(#keyword) { let tail = tail_base; #obtain return Ok(Some(#command::#variant { #params })) @@ -261,19 +261,13 @@ attribute!(commands { let tys = Punctuated::<_, Comma>::from_iter(generics.type_params()); quote! { impl<#tys> dizzle::Namespace<#command> for #state { - //def_namespace_symbols!('n |state: Self| -> #command { - //#syms - //}); - //def_namespace_exps!('n |state: Self| -> #command { - //#exps - //}); - fn namespace_symbol (&self, word: impl Symbol) -> Perhaps<#command> { + fn namespace_symbol (&self, word: &L) -> Perhaps<#command> { if let Some(word) = word.word()? { #syms } Ok(None) } - fn namespace_expression (&self, expr: impl Expression) -> Perhaps<#command> { + fn namespace_expression (&self, expr: &L) -> Perhaps<#command> { let state = self; if let Some(expr) = expr.expr()? { let head = expr.head()?; @@ -303,13 +297,13 @@ attribute!(commands { ) -> TokenStream2 { quote! { impl dizzle::Namespaced for #command { - fn namespaced_symbol (state: &T, word: L) -> Perhaps<#command> { + fn namespaced_symbol (state: &T, word: &L) -> Perhaps { if let Some(word) = word.word()? { #syms } Ok(None) } - fn namespaced_expression (state: &T, expr: L) -> Perhaps<#command> { + fn namespaced_expression (state: &T, expr: &L) -> Perhaps { if let Some(expr) = expr.expr()? { let head = expr.head()?; let tail = expr.tail()?; diff --git a/src/device/arrange.rs b/src/device/arrange.rs index 9699ab44..3bea040c 100644 --- a/src/device/arrange.rs +++ b/src/device/arrange.rs @@ -163,17 +163,17 @@ pub(self) fn toggle_bool ( } } - //pub fn per_track <'a, T: Draw + 'a, U: TracksSizes<'a>> ( + //pub fn per_track <'a, T: Draw<'_, Tui> + 'a, U: TracksSizes<'a>> ( //tracks: impl Fn() -> U + Send + Sync + 'a, //callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a - //) -> impl Draw + 'a { + //) -> impl Draw<'_, Tui> + 'a { //per_track_top(tracks, move|index, track|callback(index, track).full_h().align_y()) //} - //pub fn per_track_top <'a, T: Draw + 'a, U: TracksSizes<'a>> ( + //pub fn per_track_top <'a, T: Draw<'_, Tui> + 'a, U: TracksSizes<'a>> ( //tracks: impl Fn() -> U + Send + Sync + 'a, //callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a - //) -> impl Draw + 'a { + //) -> impl Draw<'_, Tui> + 'a { //bg(Reset, iter_east(||tracks() //.map(move|(index, track, x1, x2): (usize, &'a Track, usize, usize)|{ //fg_bg( diff --git a/src/device/arrange/clip.rs b/src/device/arrange/clip.rs index 2210da42..f3ccdf86 100644 --- a/src/device/arrange/clip.rs +++ b/src/device/arrange/clip.rs @@ -70,7 +70,7 @@ impl ClipsView for T {} pub trait ClipsView: TracksView + ScenesView { /// Draw clips per scene - fn view_scenes_clips (&self) -> impl Draw { + fn view_scenes_clips (&self) -> impl Draw<'_, Tui> { let select = self.selection(); let editor = self.editor(); let size = self.clips_size(); diff --git a/src/device/arrange/port.rs b/src/device/arrange/port.rs index 7f63b5f6..48b6a0c1 100644 --- a/src/device/arrange/port.rs +++ b/src/device/arrange/port.rs @@ -5,24 +5,24 @@ impl_has!(Vec: |self: Arrangement| self.midi_outs); impl_has!(Vec: |self: App|self.project.midi_ins); impl_has!(Vec: |self: App|self.project.midi_outs); -pub fn view_midi_ins_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw { +pub fn view_midi_ins_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw<'_, Tui> { track.map(move|track|view_ports_status(theme, "MIDI ins: ", &track.sequencer.midi_ins)) } -pub fn view_midi_outs_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw { +pub fn view_midi_outs_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw<'_, Tui> { track.map(move|track|view_ports_status(theme, "MIDI outs: ", &track.sequencer.midi_outs)) } -pub fn view_audio_ins_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw { +pub fn view_audio_ins_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw<'_, Tui> { track.map(move|track|view_ports_status(theme, "Audio ins: ", &track.audio_ins())) } -pub fn view_audio_outs_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw { +pub fn view_audio_outs_status (theme: ItemTheme, track: Option<&Track>) -> impl Draw<'_, Tui> { track.map(move|track|view_ports_status(theme, "Audio outs:", &track.audio_outs())) } pub fn view_ports_status <'a, T: JackPort> (theme: ItemTheme, title: &'a str, ports: &'a [T]) - -> impl Draw + use<'a, T> + -> impl Draw<'a, Tui> + use<'a, T> { let ins = ports.len() as u16; let frame = Outer(true, Style::default().fg(g(96))); @@ -35,7 +35,7 @@ pub fn view_ports_status <'a, T: JackPort> (theme: ItemTheme, title: &'a str, po pub fn view_io_ports <'a, T: PortsSizes<'a>> ( fg: Color, bg: Color, items: impl Fn()->T + Send + Sync + 'a -) -> impl Draw + 'a { +) -> impl Draw<'a, Tui> + 'a { type Item<'a> = (usize, &'a Arc, &'a [Connect], usize, usize); iter(items, move|(_index, name, connections, y, y2): Item<'a>, _| south( @@ -49,7 +49,7 @@ pub fn view_io_ports <'a, T: PortsSizes<'a>> ( pub struct Junction(T); impl View for Junction { - fn view (&self) -> impl Draw { + fn view (&self) -> impl Draw<'_, Tui> { T::KIND } } diff --git a/src/device/arrange/scene.rs b/src/device/arrange/scene.rs index cff99a43..99295d09 100644 --- a/src/device/arrange/scene.rs +++ b/src/device/arrange/scene.rs @@ -203,7 +203,7 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + HasClipsSize + fn w_side (&self) -> u16; fn w_mid (&self) -> u16; - fn view_scenes_names (&self) -> impl Draw { + fn view_scenes_names (&self) -> impl Draw<'_, Tui> { let select = self.selection(); let editor = self.editor(); let editing = self.is_editing(); @@ -275,13 +275,13 @@ impl HasSceneScroll for App { } } -pub fn view_scene_name ( +pub fn view_scene_name <'a> ( select: &Selection, - editor: Option<&MidiEditor>, + editor: Option<&'a MidiEditor>, index: usize, scene: &Scene, editing: bool -) -> impl Draw { +) -> impl Draw<'a, Tui> { let h = if select.scene() == Some(index) && let Some(_editor) = editor { 7 } else { diff --git a/src/device/arrange/track.rs b/src/device/arrange/track.rs index e01802d1..895a9689 100644 --- a/src/device/arrange/track.rs +++ b/src/device/arrange/track.rs @@ -46,10 +46,10 @@ impl Track { pub fn audio_outs (&self) -> &[AudioOutput] { self.devices.last().map(|x|x.audio_outs()).unwrap_or_default() } - pub fn per <'a, T: Draw + 'a, U: TracksSizes<'a>> ( + pub fn per <'a, T: Draw<'a, Tui> + 'a, U: TracksSizes<'a>> ( tracks: impl Fn() -> U + Send + Sync + 'a, callback: &'a (impl Fn(usize, &'a Track)->T + Send + Sync + 'a) - ) -> impl Draw + 'a { + ) -> impl Draw<'a, Tui> { iter_east(move||tracks().map(|(index, track, x1, x2): (usize, &Track, usize, usize)|{ fg_bg( track.color.lightest.term, @@ -343,7 +343,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra } /// Draw name of each track - fn view_track_names (&self, theme: ItemTheme) -> impl Draw { + fn view_track_names (&self, theme: ItemTheme) -> impl Draw<'_, Tui> { let selected = self.selection(); east( south( @@ -396,7 +396,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra } /// Draw outputs per track - fn view_track_outputs <'a> (&'a self, theme: ItemTheme, _h: u16) -> impl Draw { + fn view_track_outputs <'a> (&'a self, theme: ItemTheme, _h: u16) -> impl Draw<'_, Tui> { view_track_row_section(theme, south(button_2("o", "utput", false).align_w().full_w(), draw(|to: &mut Tui|{ @@ -431,7 +431,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra } /// Draw inputs per track - fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Draw { + fn view_track_inputs <'a> (&'a self, theme: ItemTheme) -> impl Draw<'_, Tui> { let mut height = 0u16; for track in self.tracks().iter() { height = height.max(track.sequencer.midi_ins.len() as u16); @@ -459,7 +459,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra }).align_w())) } - fn view_track_devices (&self, theme: ItemTheme) -> impl Draw { + fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<'_, Tui> { let height = self.tracks_devices_height(); let btn1 = button_3("d", "evice", self.track().map(|t|t.devices.len()).unwrap_or(0), false); let btn2 = button_2("D", "+", false); @@ -488,7 +488,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra h as u16 } - fn view_inputs (&self, _theme: ItemTheme) -> impl Draw + '_ { + fn view_inputs (&self, _theme: ItemTheme) -> impl Draw<'_, Tui> + '_ { let title_1 = button_3("i", "nput ", self.midi_ins().len(), false).align_w().exact_wh(20, 1); let title_2 = button_2("I", "+", false).exact_wh(4, 1); east(title_1, west(title_2, draw(move|to: &mut Tui|{ @@ -532,7 +532,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra h as u16 } - fn view_outputs (&self, theme: ItemTheme) -> impl Draw { + fn view_outputs (&self, theme: ItemTheme) -> impl Draw<'_, Tui> { let height = self.outputs_height(); let list = south( button_3( @@ -630,12 +630,12 @@ impl HasTrackScroll for App { } } -fn view_track_row_section ( +fn view_track_row_section <'a> ( _theme: ItemTheme, - button: impl Draw, - button_add: impl Draw, - content: impl Draw, -) -> impl Draw { + button: impl Draw<'a, Tui>, + button_add: impl Draw<'a, Tui>, + content: impl Draw<'a, Tui>, +) -> impl Draw<'a, Tui> { west( button_add.align_nw().exact_w(4).full_h(), east( diff --git a/src/device/browse.rs b/src/device/browse.rs index be3bb3ec..74269e57 100644 --- a/src/device/browse.rs +++ b/src/device/browse.rs @@ -118,7 +118,7 @@ impl Browse { unreachable!() }) } - //fn tui (&self) -> impl Draw { + //fn tui (&self) -> impl Draw<'_, Tui> { //iter_south_fixed(1, ||self.tui_entries(), |entry, _index|entry.origin_w().full_w()) //} //fn tui_entries (&self) -> EntriesIterator<'_, Tui> { @@ -133,7 +133,7 @@ impl Browse { } //impl<'a> Iterator for EntriesIterator<'a, Tui> { - //type Item = impl Draw; + //type Item = impl Draw<'_, Tui>; //fn next (&mut self) -> Option { //let dirs = self.browser.dirs.len(); //let files = self.browser.files.len(); @@ -179,7 +179,7 @@ pub fn scan (dir: &PathBuf) -> Usually<(Vec, Vec)> { Ok((subdirs, files)) } -pub fn view_browse_title (state: &App) -> impl Draw { +pub fn view_browse_title (state: &App) -> impl Draw<'_, Tui> { field_v(ItemTheme::default(), match state.dialog.browser_target().unwrap() { BrowseTarget::SaveProject => "Save project:", BrowseTarget::LoadProject => "Load project:", diff --git a/src/device/clock.rs b/src/device/clock.rs index fd7f811b..808ce214 100644 --- a/src/device/clock.rs +++ b/src/device/clock.rs @@ -462,7 +462,7 @@ impl_time_unit!(LaunchSync); /// let _ = tek::view_transport(true, x.as_ref(), x.as_ref(), x.as_ref()); /// let _ = tek::view_transport(false, x.as_ref(), x.as_ref(), x.as_ref()); /// ``` -pub fn view_transport (play: bool, bpm: &str, beat: &str, time: &str) -> impl Draw { +pub fn view_transport <'a> (play: bool, bpm: &str, beat: &str, time: &str) -> impl Draw<'a, Tui> { let theme = ItemTheme::G[96]; bg(Black, east!(above( button_play_pause(play, false).align_w(), @@ -479,7 +479,7 @@ pub fn view_transport (play: bool, bpm: &str, beat: &str, time: &str) -> impl Dr /// let _ = tek::view_status(None, x.as_ref(), x.as_ref(), x.as_ref()); /// let _ = tek::view_status(Some("".into()), x.as_ref(), x.as_ref(), x.as_ref()); /// ``` -pub fn view_status (sel: Option<&str>, sr: &str, buf: &str, lat: &str) -> impl Draw { +pub fn view_status <'a> (sel: Option<&str>, sr: &str, buf: &str, lat: &str) -> impl Draw<'a, Tui> { let theme = ItemTheme::G[96]; let sr = field_h(theme, "SR", sr); let buf = field_h(theme, "Buf", buf); @@ -496,7 +496,7 @@ pub fn view_status (sel: Option<&str>, sr: &str, buf: &str, lat: &str) -> impl D /// let _ = tek::button_play_pause(false, true); /// let _ = tek::button_play_pause(false, false); /// ``` -pub fn button_play_pause (playing: bool, compact: bool) -> impl Draw { +pub fn button_play_pause <'a> (playing: bool, compact: bool) -> impl Draw<'a, Tui> { bg(if playing { Rgb(0, 128, 0) } else { Rgb(128, 64, 0) }, either(compact, draw(move|to: &mut Tui|either(playing, diff --git a/src/device/dialog.rs b/src/device/dialog.rs index 06834327..2b92c56e 100644 --- a/src/device/dialog.rs +++ b/src/device/dialog.rs @@ -1,8 +1,8 @@ use crate::{*, device::*}; -pub fn draw_dialog ( - to: &mut Tui, mut frags: std::str::Split<&str>, state: &App, dsl: &impl Expression -) -> Drawn { +pub fn draw_dialog <'a, L: Language + ?Sized> ( + to: &mut Tui, mut frags: std::str::Split<&str>, state: &App, dsl: &'a L +) -> Drawn<'a, u16> { match frags.next() { Some("menu") => if let Dialog::Menu(selected, items) = &state.dialog { //Some(iter_south(move||items.0.iter().enumerate().map(move|(index, MenuItem(item, _))|{ @@ -34,7 +34,7 @@ pub fn draw_dialog ( impl App { - pub fn get_dialog (&self, src: impl Language) -> Perhaps { + pub fn get_dialog <'a> (&self, src: impl Language) -> Perhaps { src.word()?.map(|word|Ok(match word { ":dialog/none" => Dialog::None, ":dialog/options" => Dialog::Options, diff --git a/src/device/editor.rs b/src/device/editor.rs index 632e94fb..3efdf235 100644 --- a/src/device/editor.rs +++ b/src/device/editor.rs @@ -268,7 +268,7 @@ impl MidiEditor { self.get_time_pos().overflowing_sub(1) .0.min(self.clip_length().saturating_sub(1)) } - pub fn clip_status (&self) -> impl Draw + '_ { + pub fn clip_status (&self) -> impl Draw<'_, Tui> + '_ { let (_color, name, length, looped) = if let Some(clip) = self.clip().as_ref().map(|p|p.read().unwrap()) { (clip.color, clip.name.clone(), clip.length, clip.looped) } else { (ItemTheme::G[64], String::new().into(), 0, false) }; @@ -281,7 +281,7 @@ impl MidiEditor { .origin_w().full_w(), ).exact_w(20) } - pub fn edit_status (&self) -> impl Draw + '_ { + pub fn edit_status (&self) -> impl Draw<'_, Tui> + '_ { let (_color, length) = if let Some(clip) = self.clip().as_ref().map(|p|p.read().unwrap()) { (clip.color, clip.length) } else { (ItemTheme::G[64], 0) }; @@ -426,7 +426,7 @@ impl MidiViewer for MidiEditor { } impl View for MidiEditor { - fn view (&self) -> impl Draw { + fn view (&self) -> impl Draw<'_, Tui> { self.autoscroll(); /*self.autozoom();*/ self.size.of(self.mode.view()) diff --git a/src/device/editor/octave.rs b/src/device/editor/octave.rs index 21124e98..46642120 100644 --- a/src/device/editor/octave.rs +++ b/src/device/editor/octave.rs @@ -19,7 +19,7 @@ impl OctaveVertical { } impl OctaveVertical { - pub fn tui (&self) -> impl Draw { + pub fn tui (&self) -> impl Draw<'_, Tui> { east!( fg_bg(self.color(0), self.color(1), "▙"), fg_bg(self.color(2), self.color(3), "▙"), diff --git a/src/device/editor/piano.rs b/src/device/editor/piano.rs index 7b2a62de..b26a8f28 100644 --- a/src/device/editor/piano.rs +++ b/src/device/editor/piano.rs @@ -25,7 +25,7 @@ pub struct PianoHorizontal { impl_has!(Sizer: |self: PianoHorizontal| self.size); impl View for PianoHorizontal { - fn view (&self) -> impl Draw { + fn view (&self) -> impl Draw<'_, Tui> { south( east( format!("{}x{}", self.size.w(), self.size.h()).exact_w(5), @@ -132,7 +132,7 @@ impl PianoHorizontal { } } - fn notes (&self) -> impl Draw { + fn notes (&self) -> impl Draw<'_, Tui> { let time_start = self.get_time_start(); let note_lo = self.get_note_lo(); let note_hi = self.get_note_hi(); @@ -168,7 +168,7 @@ impl PianoHorizontal { }) } - fn cursor (&self) -> impl Draw { + fn cursor (&self) -> impl Draw<'_, Tui> { let note_hi = self.get_note_hi(); let note_lo = self.get_note_lo(); let note_pos = self.get_note_pos(); @@ -202,7 +202,7 @@ impl PianoHorizontal { }) } - fn keys (&self) -> impl Draw { + fn keys (&self) -> impl Draw<'_, Tui> { let state = self; let color = state.color; let note_lo = state.get_note_lo(); @@ -229,7 +229,7 @@ impl PianoHorizontal { }).exact_w(self.keys_width).full_h() } - fn timeline (&self) -> impl Draw + '_ { + fn timeline (&self) -> impl Draw<'_, Tui> + '_ { draw(move|to: &mut Tui|{ let xywh = to.area().into(); let XYWH(x, y, w, _h) = xywh; diff --git a/src/device/meter.rs b/src/device/meter.rs index 52c17949..23e72649 100644 --- a/src/device/meter.rs +++ b/src/device/meter.rs @@ -40,7 +40,7 @@ impl_draw!(|self: Log10Meter, to: Tui| { Ok(Some(to.area().into())) }); -fn draw_meters (meters: &[f32]) -> impl Draw + use<'_> { +fn draw_meters (meters: &[f32]) -> impl Draw<'_, Tui> + use<'_> { bg(Black, iter_east_fixed(1, ||meters.iter(), |value, _index|{ RmsMeter(*value).full_h() }).exact_w(2)) diff --git a/src/device/plugin.rs b/src/device/plugin.rs index fc01cf16..a3bafa53 100644 --- a/src/device/plugin.rs +++ b/src/device/plugin.rs @@ -140,7 +140,7 @@ impl ApplicationHandler for LV2PluginUI { } } -impl Draw for Lv2 { +impl Draw<'_, Tui> for Lv2 { fn draw (&self, to: &mut Tui) { let area = to.area(); let XYWH(x, y, _, height) = area; diff --git a/src/device/pool.rs b/src/device/pool.rs index 93e18234..a3e7731b 100644 --- a/src/device/pool.rs +++ b/src/device/pool.rs @@ -439,7 +439,7 @@ impl Pool { } impl<'a> PoolView<'a> { - //fn tui (&self) -> impl Draw { + //fn tui (&self) -> impl Draw<'_, Tui> { //let Self(pool) = self; ////let color = self.1.clip().map(|c|c.read().unwrap().color).unwrap_or_else(||g(32).into()); ////let on_bg = |x|x;//below(Repeat(" "), bg(color.darkest.term, x)); @@ -467,7 +467,7 @@ impl<'a> PoolView<'a> { } impl ClipLength { - //fn tui (&self) -> impl Draw { + //fn tui (&self) -> impl Draw<'_, Tui> { //use ClipLengthFocus::*; //let bars = format!("{}", self.bars()); //let beats = format!("{}", self.beats()); diff --git a/src/device/sampler.rs b/src/device/sampler.rs index f9203341..426e8a85 100644 --- a/src/device/sampler.rs +++ b/src/device/sampler.rs @@ -330,7 +330,7 @@ fn draw_list_item (sample: &Option>>) -> String { } } -fn draw_viewer (sample: Option<&Arc>>) -> impl Draw + use<'_> { +fn draw_viewer (sample: Option<&Arc>>) -> impl Draw<'_, Tui> + use<'_> { let min_db = -64.0; draw(move|to: &mut Tui|{ let xywh = to.area().into(); @@ -750,7 +750,7 @@ fn read_sample_data (_: &str) -> Usually<(usize, Vec>)> { todo!(); } -pub fn view_sample_info (sample: Option<&Arc>>) -> impl Draw + use<'_> { +pub fn view_sample_info (sample: Option<&Arc>>) -> impl Draw<'_, Tui> + use<'_> { when(sample.is_some(), draw(move|to: &mut Tui|{ let sample = sample.unwrap().read().unwrap(); let theme = sample.color; @@ -765,7 +765,7 @@ pub fn view_sample_info (sample: Option<&Arc>>) -> impl Draw })) } -pub fn view_sample_info_v (sample: Option<&Arc>>) -> impl Draw + use<'_> { +pub fn view_sample_info_v (sample: Option<&Arc>>) -> impl Draw<'_, Tui> + use<'_> { let a = draw(move|to: &mut Tui|{ let sample = sample.unwrap().read().unwrap(); let theme = sample.color; @@ -788,7 +788,7 @@ pub fn view_sample_info_v (sample: Option<&Arc>>) -> impl Draw>>) -> impl Draw { +pub fn view_sample_status (sample: Option<&Arc>>) -> impl Draw<'_, Tui> { bold(true, fg(g(224), sample .map(|sample|{ let sample = sample.read().unwrap(); diff --git a/src/device/sequence.rs b/src/device/sequence.rs index 1ccc1d9d..302c8392 100644 --- a/src/device/sequence.rs +++ b/src/device/sequence.rs @@ -113,7 +113,7 @@ pub trait HasPlayClip: HasClock { *self.reset_mut() = true; } - fn play_status (&self) -> impl Draw { + fn play_status (&self) -> impl Draw<'_, Tui> { let (name, color): (Arc, ItemTheme) = if let Some((_, Some(clip))) = self.play_clip() { let MidiClip { ref name, color, .. } = *clip.read().unwrap(); (name.clone(), color) @@ -130,7 +130,7 @@ pub trait HasPlayClip: HasClock { .into() } - fn next_status (&self) -> impl Draw { + fn next_status (&self) -> impl Draw<'_, Tui> { let mut time: Arc = String::from("--.-.--").into(); let mut name: Arc = String::from("").into(); let mut color = ItemTheme::G[64]; diff --git a/src/tek.rs b/src/tek.rs index cb5331f8..9337a78e 100644 --- a/src/tek.rs +++ b/src/tek.rs @@ -257,11 +257,11 @@ mod config { /// tek::Config::default().add(&source).unwrap().get_mode(":menu").unwrap(); /// ``` #[derive(Default, Debug)] - pub struct Config { + pub struct Config<'a> { /// XDG base directories of running user. pub dirs: BaseDirectories, /// Active collection of interaction modes. - pub modes: Modes, + pub modes: Modes<'a>, /// Active collection of event bindings. pub binds: Binds, /// Active collection of view definitions. @@ -286,7 +286,7 @@ mod config { /// assert_eq!(modes.len(), 1); /// ``` #[derive(Default, Debug, Clone)] - pub struct Modes(Arc, Arc>>>>>); + pub struct Modes<'a>(Arc, Arc>>>>>); /// Group of view and keys definitions. /// @@ -294,16 +294,16 @@ mod config { /// let mode = tek::Mode::>::default(); /// ``` #[derive(Default, Debug)] - pub struct Mode { + pub struct Mode<'a, D: Language + Ord> { pub path: PathBuf, pub name: Vec, pub info: Vec, pub view: Vec, pub keys: Vec, - pub modes: Modes, + pub modes: Modes<'a>, } - impl Config { + impl<'a> Config<'a> { /// Default configuration directory. const CONFIG_DIR: &'static str = "tek"; /// Default configuration subdirectory. @@ -389,7 +389,7 @@ mod config { /// Write initial contents of a configuration file. pub fn load Usually<()>> ( &self, path: &str, defaults: &str, mut each: F - ) -> Usually<()> { + ) -> UsuallyRef<()> { self.stamp.store(quanta::Clock::new().raw(), Relaxed); if self.find_file().is_none() { //println!("Creating {path:?}"); @@ -415,27 +415,27 @@ mod config { *self.binds.write().unwrap() = Default::default(); } /// Add one entry to the configuration. - fn add_one (&self, item: impl Language) -> Usually<()> { - if let Some(expr) = item.expr()? { - let head = expr.head()?; - let tail = expr.tail()?; - let name = tail.head()?; - let body = tail.tail()?; - match head { - Some("mode") if let Some(name) = name => self.modes.add(&name, &body)?, - Some("keys") if let Some(name) = name => load_bind(&self.binds, &name, &body)?, - Some("view") if let Some(name) = name => load_view(&self.views, &name, &body)?, - _ => return Err( - format!("Config::load: expected view/keys/mode, got: {item:?}").into() - ) - } - Ok(()) - } else { - return Err(format!("Config::load: expected expr, got: {item:?}").into()) - } + fn add_one (&'a self, item: &'a (impl Language + ?Sized)) -> UsuallyRef<'a, ()> { + item.expr()? + .map(|expr|{ + let head = expr.head()?; + let tail = expr.tail()?; + let name = tail.head()?; + let body = tail.tail()?; + match head { + Some("mode") if let Some(name) = name => self.modes.add(name, &body)?, + Some("keys") if let Some(name) = name => load_bind(&self.binds, &name, &body)?, + Some("view") if let Some(name) = name => load_view(&self.views, &name, &body)?, + _ => return Ok::, Box>(None) + } + Ok(Some(())) + }) + .transpose()? + .flatten() + .ok_or_else(||format!("Config::load: expected view/keys/mode expr, got: {item:?}").into()) } /// Get a mode by name. - pub fn get_mode (&self, mode: impl AsRef) -> Option>>> { + pub fn get_mode (&'a self, mode: impl AsRef) -> Option>>> { self.modes.get(mode) } /// Print the configuration. @@ -444,16 +444,22 @@ mod config { } } - impl Modes { + impl<'a> Modes<'a> { /// Register a mode. - pub fn add (&self, name: &impl AsRef, body: &impl Language) -> Usually<()> { + pub fn add ( + &self, + name: &'a (impl AsRef + ?Sized), + body: &(impl Language + ?Sized) + ) + -> UsuallyRef<'a, ()> + { let mut mode = Mode::default(); body.each(|item|mode.add(item))?; self.0.write().unwrap().insert(name.as_ref().into(), Arc::new(mode)); Ok(()) } /// Get a mode by name. - pub fn get (&self, name: impl AsRef) -> Option>>> { + pub fn get (&self, name: impl AsRef) -> Option>>> { self.0.read().unwrap().get(name.as_ref()).cloned() } /// Run something for each mode. @@ -468,7 +474,7 @@ mod config { } } - impl Mode> { + impl<'a> Mode<'a, Arc> { /// Add a definition to the mode. /// /// Supported definitions: @@ -483,7 +489,7 @@ mod config { /// let mut mode: tek::Mode> = Default::default(); /// mode.add("(name hello)").unwrap(); /// ``` - pub fn add (&mut self, dsl: impl Language) -> Usually<()> { + pub fn add (&mut self, dsl: &'a (impl Language + ?Sized)) -> UsuallyRef<'a, ()> { Ok(if let Ok(Some(expr)) = dsl.expr() && let Ok(Some(head)) = expr.head() { //println!("Mode::add: {head} {:?}", expr.tail()); let tail = expr.tail()?.map(|x|x.trim()).unwrap_or(""); @@ -501,23 +507,26 @@ mod config { }) } /// Add a name to the mode. - fn add_name (&mut self, dsl: impl Language) -> Perhaps<()> { - Ok(dsl.src()?.map(|src|self.name.push(src.into()))) + fn add_name (&mut self, dsl: &'a (impl Language + ?Sized)) -> PerhapsRef<'a, ()> { + Ok(dsl.text()?.map(|text|self.name.push(text.into()))) } /// Add a description to the mode. - fn add_info (&mut self, dsl: impl Language) -> Perhaps<()> { - Ok(dsl.src()?.map(|src|self.info.push(src.into()))) + fn add_info (&mut self, dsl: &'a (impl Language + ?Sized)) -> PerhapsRef<'a, ()> { + Ok(dsl.text()?.map(|text|self.info.push(text.into()))) } /// Add a view definition to the mode. - fn add_view (&mut self, dsl: impl Language) -> Perhaps<()> { - Ok(dsl.src()?.map(|src|self.view.push(src.into()))) + fn add_view (&mut self, dsl: &'a (impl Language + ?Sized)) -> PerhapsRef<'a, ()> { + Ok(dsl.text()?.map(|text|self.view.push(text.into()))) } /// Add a keyboard input bindin to the mode. - fn add_keys (&mut self, dsl: impl Language) -> Perhaps<()> { - Ok(Some(dsl.each(|expr|{ self.keys.push(expr.trim().into()); Ok(()) })?)) + fn add_keys (&mut self, dsl: &'a (impl Language + ?Sized)) -> PerhapsRef<'a, ()> { + Ok(Some(dsl.src()?.each(|expr|{ + self.keys.push(expr.trim().into()); + Ok::<(), Box>(()) + })?)) } /// Add a submode to the mode. - fn add_mode (&mut self, dsl: impl Language) -> Perhaps<()> { + fn add_mode (&mut self, dsl: &'a (impl Language + ?Sized)) -> PerhapsRef<'a, ()> { Ok(Some(if let Some(id) = dsl.head()? { self.modes.add(&id, &dsl.tail())?; } else { @@ -599,7 +608,7 @@ mod app { /// Performance counter pub perf: PerfModel, /// Available view modes and input bindings - pub config: Arc, + pub config: Arc>, /// Currently selected mode pub mode: Option>, /// Undo history @@ -640,17 +649,17 @@ mod app { } } - fn get_arc_str (_: &App, src: impl Language) -> Perhaps> { + fn get_arc_str <'a> (_: &App, src: impl Language) -> Perhaps> { Ok(src.src()?.map(|x|x.into())) } - fn get_u16 (state: &App, src: impl Language) -> Perhaps { + fn get_u16 <'a> (state: &App, src: impl Language) -> Perhaps { Ok(Some(match src.word()? { Some(":w/sidebar") => state.project.w_sidebar(state.editor().is_some()), Some(":h/sample-detail") => 6.max(state.size.h() as u16 * 3 / 9), _ => return try_to_u16(src) })) } - fn get_usize (state: &App, src: impl Language) -> Perhaps { + fn get_usize <'a> (state: &App, src: impl Language) -> Perhaps { Ok(Some(match src.word()? { Some(":scene-count") => state.scenes().len(), Some(":track-count") => state.tracks().len(), @@ -660,7 +669,7 @@ mod app { _ => return try_to_usize(src) })) } - fn get_bool (state: &App, src: impl Language) -> Perhaps { + fn get_bool <'a> (state: &App, src: impl Language) -> Perhaps { src.word()?.map(|word|Ok(match word { "Y" => true, "N" => false, @@ -681,7 +690,7 @@ mod app { })).transpose() } #[allow(unused)] - fn get_selection (state: &App, src: impl Language) -> Perhaps { + fn get_selection <'a> (state: &App, src: impl Language) -> Perhaps { src.word()?.map(|word|Ok(match word { ":select/scene" => state.selection().select_scene(state.tracks().len()), ":select/scene/next" => state.selection().select_scene_next(state.scenes().len()), @@ -692,21 +701,21 @@ mod app { _ => return Err(format!("not selection: {word}").into()) })).transpose() } - fn get_color (_: &App, src: impl Language) -> Perhaps { + fn get_color <'a> (_: &App, src: impl Language) -> Perhaps { if let Some(expr) = src.expr()? { match (expr.head()?, expr.tail()?) { (Some("g"), Some(tail)) => { let n = try_to_u8(tail.head().map_err(Into::into))? - .ok_or(LanguageError::Domain("not gray"))?; + .ok_or(LanguageError::domain("not gray"))?; Ok(Some(Color::Rgb(n, n, n))) }, (Some("rgb"), Some(tail)) => { let r = try_to_u8(tail.head().map_err(Into::into))? - .ok_or(LanguageError::Domain("not red"))?; + .ok_or(LanguageError::domain("not red"))?; let g = try_to_u8(tail.tail().head().map_err(Into::into))? - .ok_or(LanguageError::Domain("not green"))?; + .ok_or(LanguageError::domain("not green"))?; let b = try_to_u8(tail.tail().tail().head().map_err(Into::into))? - .ok_or(LanguageError::Domain("not blue"))?; + .ok_or(LanguageError::domain("not blue"))?; Ok(Some(Color::Rgb(r, g, b))) }, (Some(_), _) => return Err(format!("not a color expression: {expr}").into()), @@ -723,7 +732,7 @@ mod app { } } #[allow(unused)] - fn get_opt_u7 (state: &App, src: impl Language) -> Perhaps> { + fn get_opt_u7 <'a> (state: &App, src: impl Language) -> Perhaps> { src.word()?.map(|word|Ok(match word { ":editor/pitch" => Some(( state.editor().as_ref().map(|e|e.get_note_pos()).unwrap() as u8 @@ -731,7 +740,7 @@ mod app { _ => return Err(format!("unknown midi note: {word}").into()) })).transpose() } - fn get_opt_usize (state: &App, src: impl Language) -> Perhaps> { + fn get_opt_usize <'a> (state: &App, src: impl Language) -> Perhaps> { src.word()?.map(|word|Ok(match word { ":selected/scene" => state.selection().scene(), ":selected/track" => state.selection().track(), @@ -739,42 +748,42 @@ mod app { })).transpose() } #[allow(unused)] - fn get_clip (state: &App, src: impl Language) -> Perhaps>>> { + fn get_clip <'a> (state: &App, src: impl Language) -> Perhaps>>> { src.word()?.map(|word|Ok(match word { ":selected/clip" if let Selection::TrackClip { track, scene } = state.selection() => state.scenes()[*scene].clips[*track].clone(), _ => return Err(format!("not a clip: {word}").into()) })).transpose() } - fn get_axis (_: &App, src: impl Language) -> Perhaps { + fn get_axis <'a> (_: &App, src: impl Language) -> Perhaps { Ok(src.word()?.map(|word|Ok(match word { ":x" => ControlAxis::X, ":y" => ControlAxis::Y, _ => return Err(format!("unknown axis {word}")) })).transpose()?) } - fn get_opt_u16 (_: &App, _src: impl Language) -> Perhaps> { + fn get_opt_u16 <'a> (_: &App, _src: impl Language) -> Perhaps> { Ok(None) } - fn get_opt_itemtheme (_: &App, _: impl Language) -> Perhaps> { + fn get_opt_itemtheme <'a> (_: &App, _: impl Language) -> Perhaps> { todo!() } - fn get_opt_vec_opt_arc_rwlock_midiclip (_: &App, _: impl Language) -> Perhaps>>>>> { + fn get_opt_vec_opt_arc_rwlock_midiclip <'a> (_: &App, _: impl Language) -> Perhaps>>>>> { todo!() } - fn get_opt_arc_array_connect (_: &App, _: impl Language) -> Perhaps>> { + fn get_opt_arc_array_connect <'a> (_: &App, _: impl Language) -> Perhaps>> { todo!() } - fn get_arc_array_connect (_: &App, _: impl Language) -> Perhaps> { + fn get_arc_array_connect <'a> (_: &App, _: impl Language) -> Perhaps> { todo!() } - fn get_opt_arc_str (_: &App, _: impl Language) -> Perhaps>> { + fn get_opt_arc_str <'a> (_: &App, _: impl Language) -> Perhaps>> { todo!() } - fn get_opt_bool (_: &App, _: impl Language) -> Perhaps> { + fn get_opt_bool <'a> (_: &App, _: impl Language) -> Perhaps> { todo!() } - fn get_path_buf (_: &App, _: impl Language) -> Perhaps { + fn get_path_buf <'a> (_: &App, _: impl Language) -> Perhaps { todo!() } } @@ -976,13 +985,15 @@ mod bind { } } - pub(crate) fn load_bind (binds: &Binds, name: &impl AsRef, body: &impl Language) -> Usually<()> { + pub(crate) fn load_bind <'a> ( + binds: &Binds, name: &impl AsRef, body: &impl Language + ) -> Usually<()> { binds.write().unwrap().insert(name.as_ref().into(), Bind::load(body)?); Ok(()) } impl Bind> { - pub fn load (lang: &impl Language) -> Usually { + pub fn load <'a> (lang: &impl Language) -> Usually { let mut map = Self::new(); lang.each(|item|if item.expr().head() == Ok(Some("see")) { // TODO @@ -1269,7 +1280,7 @@ mod device { } } - pub fn view_device (state: &App) -> impl Draw { + pub fn view_device (state: &App) -> impl Draw<'_, Tui> { let selected = state.dialog.device_kind().unwrap(); south( bold(true, "Add device"), @@ -1301,9 +1312,9 @@ mod draw { use crate::*; /// Load custom view definition. - pub(crate) fn load_view ( - views: &Views, name: &impl AsRef, body: &impl Language, - ) -> Usually<()> { + pub(crate) fn load_view <'a> ( + views: &Views, name: &impl AsRef, body: &'a impl Language, + ) -> UsuallyRef<'a, ()> { views.write().unwrap().insert( name.as_ref().into(), body.src()?.unwrap_or_default().into() @@ -1311,23 +1322,13 @@ mod draw { Ok(()) } - impl Keywords> for App { - fn keywords () -> impl Iterator Perhaps>> { - [ - kw_when, kw_either, kw_split, kw_align, kw_exact, kw_min, kw_max, kw_push, kw_full, - kw_tui_text, kw_tui_fg, kw_tui_bg - ] - .into_iter() - } - } - /// The [Draw] implementation for [App] handles the loaded view, /// which is defined in terms of [dizzle] DSL. /// /// If there is an error, the error is displayed. FIXME: overlay it /// Then, every top-level form of the DSL description is rendered. impl View for App { - fn view (&self) -> impl Draw { + fn view (&self) -> impl Draw<'_, Tui> { //self.perf.cycle(&mut |_|{ draw(|to: &mut Tui|{ self.draw_error(to)?; @@ -1347,15 +1348,8 @@ mod draw { Ok(()) } - fn draw_mode (&self, to: &mut Tui) -> Usually<()> { - self.mode.as_ref().and_then(|m|self.config.get_mode(m)).map(|mode|{ - //south!( - //format!("Mode: {:?}", self.mode.as_ref()), - //format!("Time: {}", self.config.stamp.load(Relaxed)), - //iter_south(||mode.view.iter().enumerate().map(|(index, line)|{ - //format!("View #{index} {line}") - //})) - //).align_nw().draw(to)?; + fn draw_mode <'a> (&'a self, to: &mut Tui) -> UsuallyRef<'a, ()> { + if let Some(mode) = self.mode.as_ref().and_then(|m|self.config.get_mode(m)) { for (index, dsl) in mode.view.iter().enumerate() { match self.interpret(to, dsl) { Ok(Some(XYWH(.., w, h))) => { @@ -1364,7 +1358,10 @@ mod draw { }, Err(e) => { let src = &dsl.src().unwrap_or(Some("")).unwrap_or(""); - let message = format!("Mode: {:?}\n\nLayer: #{index}\n\nError: {e}\n\nSource:\n{}", &mode.name, &src); + let message = format!( + "Mode: {:?}\n\nLayer: #{index}\n\nError: {e}\n\nSource:\n{src}", + &mode.name + ); *self.error.write().unwrap() = Some(message.into()); return Err(e); }, @@ -1372,8 +1369,7 @@ mod draw { } } *self.error.write().unwrap() = None; - Ok(()) - }); + } Ok(()) } @@ -1385,11 +1381,21 @@ mod draw { } } - impl Interpret>> for App { - fn interpret_expr <'a> (&'a self, to: &mut Tui, lang: &'a impl Expression) -> Drawn { - self.keyword(to, lang) + impl<'a> Interpret<'a, Tui, Option>> for App { + + fn interpret_expr (&'a self, to: &mut Tui, src: &'a L) -> Drawn { + if let Some(src) = src.src()? { + interpret_keyword!(self, to, src, [ + kw_when, kw_either, kw_split, kw_align, kw_exact, kw_min, kw_max, kw_push, kw_full, + kw_tui_text, kw_tui_fg, kw_tui_bg + ]); + Err(format!("interpret_expr: unexpected: {src:?}").into()) + } else { + Err(format!("interpret_expr: no keyword: {src:?}").into()) + } } - fn interpret_word <'a> (&'a self, to: &mut Tui, lang: &'a impl Expression) -> Drawn { + + fn interpret_word (&'a self, to: &mut Tui, lang: &'a L) -> Drawn { let mut frags = lang.src()?.unwrap().split("/"); match frags.next() { //Some(":logo") => view_logo().draw(to), @@ -1433,6 +1439,7 @@ mod draw { _ => unreachable!() } } + } impl_has!(Sizer: |self: App|self.size); @@ -1445,7 +1452,7 @@ mod draw { fn width_dec (&mut self); } - pub fn view_templates (_frags: std::str::Split<&str>, state: &App) -> impl Draw { + pub fn view_templates <'a> (_frags: std::str::Split<&str>, state: &App) -> impl Draw<'a, Tui> { let height = (state.config.modes.len() * 2) as u16; draw(move |to: &mut Tui|{ let mut index = 0; @@ -1466,17 +1473,17 @@ mod draw { }).min_w(30).exact_h(height) } - pub fn field_h ( - _theme: ItemTheme, _head: impl Draw, _body: impl Draw - ) -> impl Draw { + pub fn field_h <'a, T: Screen> ( + _theme: ItemTheme, _head: impl Draw<'a, T>, _body: impl Draw<'a, T> + ) -> impl Draw<'a, T> { } - pub fn field_v ( - _theme: ItemTheme, _head: impl Draw, _body: impl Draw - ) -> impl Draw { + pub fn field_v <'a, T: Screen> ( + _theme: ItemTheme, _head: impl Draw<'a, T>, _body: impl Draw<'a, T> + ) -> impl Draw<'a, T> { } - pub fn view_sessions () -> impl Draw { + pub fn view_sessions <'a> () -> impl Draw<'a, Tui> { let h = 6; let w = Some(30); let f = Rgb(224, 192, 128); @@ -1490,12 +1497,15 @@ mod draw { Ok(Some(to.area().into())) }).min_w(w).exact_h(h) } + /// ``` /// let bg = tengri::ratatui::style::Color::Red; /// let fg = tengri::ratatui::style::Color::Green; /// let _ = tek::view_wrap(bg, fg, "and then blue, too!"); /// ``` - pub fn view_wrap (bg: Color, fg: Color, content: impl Draw) -> impl Draw { + pub fn view_wrap <'a> (bg: Color, fg: Color, content: impl Draw<'a, Tui>) + -> impl Draw<'a, Tui> + { let left = fg_bg(bg, Reset, y_repeat("▐").exact_w(1)); let right = fg_bg(bg, Reset, y_repeat("▌").exact_w(1)); east(left, west(right, fg_bg(fg, bg, content))) @@ -1505,7 +1515,9 @@ mod draw { /// let _ = tek::view_meter("", 0.0); /// let _ = tek::view_meters(&[0.0, 0.0]); /// ``` - pub fn view_meter <'a> (label: &'a str, value: f32) -> impl Draw + 'a { + pub fn view_meter <'a> (label: &'a str, value: f32) + -> impl Draw<'a, Tui> + { let f = field_h(ItemTheme::G[128], label, format!("{:>+9.3}", value)); let w = if value >= 0.0 { 13 } else if value >= -1.0 { 12 } @@ -1527,13 +1539,15 @@ mod draw { south!(f, bg(c, ()).exact_wh(w, 1)) } - pub fn view_meters (values: &[f32;2]) -> impl Draw + use<'_> { + pub fn view_meters (values: &[f32;2]) -> impl Draw<'_, Tui> + use<'_> { let left = format!("L/{:>+9.3}", values[0]); let right = format!("R/{:>+9.3}", values[1]); south(left, right) } - pub fn view_track_header (theme: ItemTheme, content: impl Draw) -> impl Draw { + pub fn view_track_header <'a> (theme: ItemTheme, content: impl Draw<'a, Tui>) + -> impl Draw<'a, Tui> + { bg(theme.darker.term, content.align_e().full_w()).exact_w(12) } @@ -1541,7 +1555,9 @@ mod draw { /// let _ = tek::button_2("", "", true); /// let _ = tek::button_2("", "", false); /// ``` - pub fn button_2 <'a> (key: impl Draw, label: impl Draw, hide: bool) -> impl Draw { + pub fn button_2 <'a> (key: impl Draw<'a, Tui>, label: impl Draw<'a, Tui>, hide: bool) + -> impl Draw<'a, Tui> + { let c1 = tui_orange(); let c2 = tui_g(0); let c3 = tui_g(96); @@ -1555,8 +1571,11 @@ mod draw { /// let _ = tek::button_3("", "", "", false); /// ``` pub fn button_3 <'a> ( - key: impl Draw, label: impl Draw, value: impl Draw, editing: bool, - ) -> impl Draw { + key: impl Draw<'a, Tui>, + label: impl Draw<'a, Tui>, + value: impl Draw<'a, Tui>, + editing: bool, + ) -> impl Draw<'a, Tui> { let c1 = tui_orange(); let c2 = tui_g(0); let c3 = tui_g(96); diff --git a/tengri b/tengri index 95ace837..291ab632 160000 --- a/tengri +++ b/tengri @@ -1 +1 @@ -Subproject commit 95ace837565c65292d86694cb395d9ba7fa834eb +Subproject commit 291ab632245c8beb83973da4f5157eb7b40cc7eb